c ++, что произойдет, если вы напечатаете больше символов с помощью sprintf, чем выделено указателем char? - PullRequest
2 голосов
/ 26 мая 2009

Я предполагаю, что это распространенный способ использования sprintf:

char pText[x];
sprintf(pText, "helloworld %d", Count );

но что именно происходит, если указателю char выделено меньше памяти, чем он будет печатать?

т.е. что если x меньше длины второго параметра sprintf?

Я спрашиваю, поскольку я получаю странное поведение в коде, который следует за оператором sprintf.

Ответы [ 6 ]

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

Невозможно ответить "точно", что именно произойдет. Это вызывает то, что называется Неопределенное поведение , что в основном означает, что может произойти все что угодно.

Хорошей идеей будет просто избегать таких случаев и использовать безопасные функции там, где они доступны:

char pText[12];
snprintf(pText, sizeof pText, "helloworld %d", count);

Обратите внимание, как <a href="http://linux.die.net/man/3/snprintf" rel="nofollow noreferrer">snprintf()</a> принимает дополнительный аргумент, который является размером буфера, и не будет писать больше, чем есть место.

6 голосов
/ 26 мая 2009

Это распространенная ошибка, которая приводит к перезаписи памяти в массиве символов. Так, например, в памяти после массива char могут быть некоторые целые или другой массив, и они будут перезаписаны текстом.

Смотрите хорошее подробное описание всей проблемы (переполнения буфера) здесь . Также есть комментарий, что некоторые архитектуры предоставляют подпрограмму snprintf с четвертым параметром, который определяет максимальную длину (в вашем случае x). Если ваш компилятор этого не знает, вы также можете написать его самостоятельно, чтобы убедиться, что вы не можете получить такие ошибки (или просто убедиться, что у вас всегда достаточно места).

Обратите внимание, что поведение после такой ошибки не определено и может привести к очень странным ошибкам. Переменные обычно выровнены в ячейках памяти, кратных 4, поэтому вы иногда не заметите ошибку в большинстве случаев, когда вы записали слишком много одного или двух байтов (т.е. забыли освободить место для NUL), но получите странные ошибки в других случаев. Эти ошибки трудно отладить, потому что другие переменные изменяются, и ошибки часто будут возникать в совершенно другой части кода.

3 голосов
/ 26 мая 2009

Это называется переполнением буфера .

sprintf перезапишет память, которая следует за pText по адресу. Поскольку pText находится в стеке, sprintf может перезаписывать локальные переменные, аргументы функций и адрес возврата, что приводит ко всем видам ошибок. Многие уязвимости безопасности возникают в результате такого рода кода - например, злоумышленник использует переполнение буфера, чтобы написать новый адрес возврата, указывающий на его собственный код.

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

Поведение в этой ситуации не определено. Как правило, у вас происходит сбой, но вы также можете не видеть никаких побочных эффектов, странных значений, появляющихся в несвязанных переменных, и тому подобное. Ваш код может также вызывать неправильные функции, форматировать жесткий диск и убивать другие работающие программы. Лучше решить эту проблему, выделив больше памяти для вашего буфера.

1 голос
/ 19 мая 2010

Я делал это много раз, вы получите ошибку повреждения памяти. AFAIK, я помню, я сделал что-то вроде этого: -

vector<char> vecMyObj(10);
vecMyObj.resize(10);
sprintf(&vecMyObj[0],"helloworld %d", count); 

Но когда вызывается деструктор vector, моя программа получает ошибку повреждения памяти, если ее размер меньше 10, она будет работать успешно.

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

Можете ли вы произнести Переполнение буфера ? Одним из возможных результатов будет повреждение стека, что сделает ваше приложение уязвимым для использования в стеке.

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