Luigi 2201
Luigi 2201

Reputation: 13

Variable unexpectedly changed to 0 after cin to different variable

I have a problem with my program in c++: this program unexpectedly sets my variable n_alunni to 0 when I cin >> verify; even though I haven't written anything else to n_alunni.

This is the code:

#include <iostream>
#include <string>
using namespace std;

int main()
{
    int n_alunni=1;
    char verify[1];

    cout<<"Inserisci il numero di alunni: ";
    cin>>n_alunni; // I set it to something > 0

    cout<<n_alunni; // n_alunni > 0
    cout<<"Sicuro di voler inserire "<<n_alunni<<" alunni (y,n)?   ";
    cin>>verify;      // <-- After I insert into verify, n_alunni suddenly equals 0
    cout<<n_alunni; // n_alunni == 0
}

Can anyone help me please, thanks everyone in advance

Upvotes: 1

Views: 365

Answers (2)

Peter - Reinstate Monica
Peter - Reinstate Monica

Reputation: 16120

The input into verify is writing beyond the array bounds, overwriting other memory, among it your variable. Use std::string instead or at least increase the array size beyond the expected input length (and, for a safe program, protect against boundary violations!).

In more detail, the array argument is, as is the case in many contexts, "adjusted" to a pointer to char; this matches the istream& operator>> (istream& is, char* s). This operator copies a "word" from the standard input into the memory pointed to. It skips any whitespace (for example, the newline left behind from when you last hit the enter key) and then copies characters from stdin to the indicated memory location; it stops before the next whitespace in the input (for example, the newline produced when you hit the enter key to "finish your input"). After the input characters are written the routine terminates the entered 1-character "word" with a null character so that it is a proper "C string" after the crude fashion that was modern in 1978.

If you entered a one-character word, that null character gets written to memory adjacent to your 1-char array, in this case n_alunni. (You can verify that hypothesis by entering a number into n_alunni that is larger than 255, thus altering more bytes which will not be affected by the zero byte. On an intel architecture the new value of n_alunni after a one-character input should then be n_alunni & ~0xff; that is, the same as after the input with the lowest byte zeroed out).

As is often the case, using std::string for text is a safer way to handle unknown text. There is an istream& operator>> (istream& is, string& str) that works just like the char * overload, only safer.

Upvotes: 1

Rob G
Rob G

Reputation: 3526

As Peter said in his answer, and TomLyngmo in his comment, trying to cin to a char[] (verify) makes C++ think you want to write a C-string, which always has a 'null terminator' to indicate the end of the string. However, your char[] is only length 1, so unless you don't insert anything into it, it will try to write beyond the end of the array, causing this undefined behavior (changing other variables randomly).

Since your verify doesn't need to be a C-string, you could change it to just char verify and remove any of the array-access business from it. cin should then see it as a proper char and not try to write any null terminator after it, avoiding the memory overwrite you're seeing that results in unexpectedly changing the value of the other variable to 0.

Upvotes: 2

Related Questions