Это переполнение буфера. Скорее всего, при компиляции на Windows, переменная counter
немедленно следует s[5]
переменных в памяти, как это:
+----+----+----+----+----+----+----+----+----+
| ?? | ?? | ?? | ?? | ?? | 01 | 00 | 00 | 00 |
+----+----+----+----+----+----+----+----+----+
\________ s[5] ________/ \____ counter ____/
Начиная с Windows является прямым порядком байт, он хранится в 01 00 00 00
вместо 00 00 00 01
, как можно было бы ожидать. ??
просто указывает, что мы еще не знаем, что там - это может быть что угодно.
Теперь предположим, что вы ввели «Hardy» и нажмите Enter. В ASCII это преобразуется в последовательность байтов 48 61 72 64 79 0D 0A
(последние две строки заканчиваются, в UNIX 0D
будет опущен). Это то, что будет делать cin >> s
памяти:
1. Read in 'H':
+----+----+----+----+----+----+----+----+----+
| 48 | ?? | ?? | ?? | ?? | 01 | 00 | 00 | 00 |
+----+----+----+----+----+----+----+----+----+
2. Read in 'a':
+----+----+----+----+----+----+----+----+----+
| 48 | 61 | ?? | ?? | ?? | 01 | 00 | 00 | 00 |
+----+----+----+----+----+----+----+----+----+
3. Read in 'r':
+----+----+----+----+----+----+----+----+----+
| 48 | 61 | 72 | ?? | ?? | 01 | 00 | 00 | 00 |
+----+----+----+----+----+----+----+----+----+
4. Read in 'd':
+----+----+----+----+----+----+----+----+----+
| 48 | 61 | 72 | 64 | ?? | 01 | 00 | 00 | 00 |
+----+----+----+----+----+----+----+----+----+
5. Read in 'y':
+----+----+----+----+----+----+----+----+----+
| 48 | 61 | 72 | 64 | 79 | 01 | 00 | 00 | 00 |
+----+----+----+----+----+----+----+----+----+
6. Read in '\r\n' (or on UNIX, just '\n'), but this isn't put into the memory.
Instead, cin realizes that it has finished reading, and closes off the string with a '\0':
+----+----+----+----+----+----+----+----+----+
| 48 | 61 | 72 | 64 | 79 | 00 | 00 | 00 | 00 |
+----+----+----+----+----+----+----+----+----+
\________ s[5] ________/ \____ counter ____/
Упс! Он переписал счетчик!
Почему это нормально работает в Linux? Либо Linux не поместить две переменные смежны в памяти, или система Linux является большой обратный порядок байт, который будет означать, что память вместо выкладывается так:
+----+----+----+----+----+----+----+----+----+
| ?? | ?? | ?? | ?? | ?? | 00 | 00 | 00 | 01 |
+----+----+----+----+----+----+----+----+----+
Таким образом, даже если вы читаете в 5 символов, конечный нулевой ограничитель просто заменяет 0, который уже был там. Конечно, если это причина, то чтение в 6 персонажах действительно испортит ситуацию.
И как вы его исправите? Проблема в том, что для хранения строки длиной n
массив символов должен иметь длину n+1
. Таким образом, вы можете сделать это:
char s[6];
Или еще лучше, используйте строку:
std::string s;
(Для этого вам нужно #include <string>
.)
Как долго строки вы читаете в массив 's'? Все, что превышает 4 символа (плюс терминатор NUL), переполнит массив и уничтожит следующую память, возможно, включая вашу переменную 'counter'. – Blastfurnace