Что просходит? получает () - PullRequest
2 голосов
/ 14 мая 2009

Давайте рассмотрим две строки:

char input[1];
gets(input);

Допустим, ввод "тест". printf ("% s \ n", input) => "test", но если я использую отладчик, я вижу input [0] = 't' no input [1] ... Что именно происходит?

Ответы [ 6 ]

10 голосов
/ 14 мая 2009

Это переполнение буфера, к вашему сведению. Для развлечения добавьте char untouched[20]; после char input[1];, а также напечатайте untouched. Не используйте gets(), используйте fgets() или что-то еще с проверкой границ.

Отладчик не показывает input[1], потому что такой вещи нет. Ваше объявление char input[1]; выделяет массив длиной 1, а не массив от 0 до 1.

7 голосов
/ 14 мая 2009

получает (и) читает строку из стандартного ввода в буфер указывает на s до либо завершающий перевод строки, либо EOF, который он заменяет на '\ 0'. Нет проверки для переполнения буфера выполняется

http://linux.die.net/man/3/gets

Когда вы выполняете get, ввод записывается в буфер, на который указывает s. Затем он добавляет \ 0. Только 't' находится внутри входного буфера. Остальное расположено на непрерывной памяти в стеке. printf печатает «test», потому что он может читать, начиная с s до первого \ 0. Но «est \ 0» находятся вне буфера.

 ------
|  t  |  input - Debugger only sees this position.
 ------
|  e  |  Memory you are stepping onto. Trouble if it doesn´t belong to your proc.   
|  s  | 
|  t  |
|  \0 |
------

Когда вы отлаживаете, input указывает только на один символ, так что это все, что вы можете увидеть.

Важно взглянуть на "Проверка переполнения буфера не выполняется" . Это означает, что функция get не заботится о том, выделена ли память для ввода. Он просто начнет копировать все это с той точки, которую вы указали. Если вы не будете осторожны, ваш вклад может повлиять на важную информацию. В некоторых наихудших случаях это будет адрес возврата для вашей функции (где вы используете get). Кто-то, кто «просто делает» эту ошибку, скажет, «что происходит». Кто-то, кто намеренно делает это, направит ваш адрес возврата на определенную часть и выполнит код, расположенный там.

Подробнее о переполнении буфера.

2 голосов
/ 14 мая 2009

Это:

char input[1];

резервирует память только одного персонажа, но затем вы вводите пять символов.

Отладчик знает, что у вас есть только один персонаж, и покажет вам, что он знает.

Запущенная программа разбрызгивает строку по любой памяти, смежной с input, и либо вылетает, либо сходит с рук. В твоем случае тебе это сходит с рук.

2 голосов
/ 14 мая 2009

Вы переполняете свой буфер, вот что происходит. Ты пишешь в память, которая не твоя, и тебе везет.

1 голос
/ 14 мая 2009

Символ [] длины n имеет последнюю запись, сохраненную в позиции n-1. Таким образом,

char input[1];

означает данные одного типа символа, хранящиеся во входных данных массива, позиция 0.

(отредактировано для уточнения - первая формулировка была слишком плохой.)

0 голосов
/ 14 мая 2009

Вы объявляете массив с фиксированным размером '1'. Индекс первого элемента в массиве всегда равен 0. Вот почему input [0] содержит символ 't'.

РЕДАКТИРОВАТЬ - Остальное хранится где-то за пределами буфера (BufferOverFlow).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...