Reputation: 13
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
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
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