1

I have no idea why suddenly the value of integer is changing even though there's no process of caluclation, here's the code of my program :

#include <iostream>
using namespace std;

int main()
{
    int n;

    int a[] = {};
    int b[] = {};

    cin >> n;
    cout << "\n";

    for(int i=0;i<n;i++)
        cin >> a[i];

    cout << "\n";

    for(int i=0;i<n;i++)
        cin >> b[i];

    cout << "\n";

    for(int i=0;i<n;i++)
        cout << a[i] << " " << b[i] << "\n";

    cout << n;
}

So if I input the value of n lower than 5, there's no problem with the code. But if I put the value of n higher than 4, the value of integer a[i] will follow the value of b[i] somehow and the value of n is different from what I input. As for example it's like this Input :

10

1
2
3
4
5
6
7
8

91
92
93
94
95
96
97
98

Output :

95 91
96 92
97 93
98 94
5 95
6 96
7 97
8 98
8

As you can see the value of n changing from 10 to 8, and the loop only happen for 8 times. Why the value of n and a[i] are changing? Any help is appreciated, thanks

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Yasamura
  • 41
  • 3
  • 2
    use std::vector not arrays – pm100 Feb 03 '22 at 18:24
  • Your code has undefined behaviour, since it modifies non-existent elements of arrays (which have size zero). When behaviour is undefined, any outcome is possible - including some variable getting an unexpected value. Rather than playing with raw arrays in any form, use `std::vector` (and remember to resize appropriately and/or use available techniques to avoid accessing non-existent elements). – Peter Feb 03 '22 at 23:14

2 Answers2

3

These declarations

int a[] = {};
int b[] = {};

invoke undefined behavior because you may not declare arrays with the number of elements equal to 0.

It seems you are trying to use variable length arrays that is not a standard C++ feature.

Nevertheless if the compiler supports this feature then you need at least to write

int n;

cin >> n;
cout << "\n";

int a[n];
int b[n];

for(int i=0;i<n;i++)
    cin >> a[i];

That is you may declare the arrays after the variable n will have a positive value.

But it is much better not to use non-standard language extensions. So instead of the variable length arrays you should use the standard container std::vector<int>.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

You should declare your arrays a and b like this after the line cin >> n:

int a[n];
int b[n];

to avoid undefined behavior as Vlad said. Declaring array length like that at runtime isn't standard in c++ so you could instead use a std::vector or malloc like:

int n;

cin >> n;
cout << "\n";

int *a = (int *) malloc(n*sizeof(int));
int *b = (int *) malloc(n*sizeof(int));
NO_GUI
  • 444
  • 8
  • 12
  • 2
    [Why aren't variable-length arrays part of the C++ standard?](https://stackoverflow.com/questions/1887097/why-arent-variable-length-arrays-part-of-the-c-standard) – user4581301 Feb 03 '22 at 18:23
  • Ahh right I forgot about that, std::vector would be better then or using malloc() – NO_GUI Feb 03 '22 at 18:57
  • The order of preference would go something like `vector`, smart pointer to dynamic array, raw pointer to object allocated with `new[]`, and then `malloc`. In C++ `malloc` almost always comes in dead last. – user4581301 Feb 03 '22 at 19:00
  • Oh, why isn't malloc preferred? – NO_GUI Feb 03 '22 at 19:05
  • `malloc` and family are C functions and only provide raw memory. They cannot call constructors. Not so important for `int`s, but `malloc` also has to be passed a correct size (a chance for the programmer to screw up), the return value has to tested to ensure memory was indeed allocated (another place for the programmer to screw up) and the return value needs to be be cast to the correct type (compiler will catch you if you screw this up). – user4581301 Feb 03 '22 at 19:10
  • `malloc()` is not preferred in C++, because a `new` expression is a better alternative (e.g. it works to properly initialise types, which `malloc()` does not) in C++. But even using a `new` expression is discouraged in modern C++, because it has similar weaknesses to `malloc()` - such as the potential to forget to release it - and usage of standard containers (from the standard library) is preferred instead, Net effect: your code is advocating techniques considered bad practice in C++. – Peter Feb 03 '22 at 23:19
  • ahhh I see just more chances for error – NO_GUI Feb 03 '22 at 23:50
  • In the case of an `int`, yes. `malloc` a `std::string` and you're really see things go nuts. A `std::string` is a timebomb if you don't construct it. You could use [placement new](https://en.cppreference.com/w/cpp/language/new#Placement_new) to construct an object in a `malloc`ed block of memory, but it's a pain best reserved for strange edge cases. – user4581301 Feb 04 '22 at 01:04