неправильное использование sprintf? - PullRequest
3 голосов
/ 18 ноября 2010

У меня есть простая тестовая программа

#include <stdio.h>
int main( int argc , char* argv[] )
{
  unsigned int number=2048;

  char* cpOut;
  char cOut[4]; 
  cpOut=(char*)&cOut[0];
  printf("cOut address= %x \n",&cOut[0]);
  printf("cpOut address = %x \n",cpOut);

  sprintf(&cOut[0],"%d \n", number);

  printf("cOut address= %x \n",&cOut[0]);
  printf("cpOut address = %x \n",cpOut);
};

Тестовый запуск в Linux, gcc 4.3.4:

user@server /tmp $ ./a.out 
cOut address= f9f41880 
cpOut address = f9f41880 
cOut address= f9f41880 
cpOut address = f9f41880 

Тестовый запуск на Solaris 10, Sun C ++ 5.10:

bash-3.00$ ./a.out
cOut address= 8047488
cpOut address = 8047488
cOut address= 8047488
cpOut address = 8000a20

Может кто-нибудь объяснить, почему указатель cpOut перезаписывается при вызове функции sprintf?

Ответы [ 4 ]

6 голосов
/ 18 ноября 2010

Поскольку строка "2048 \n" не помещается в char cOut[4];, вы создаете переполнение буфера.

4 голосов
/ 18 ноября 2010

Вы записываете 7 байтов ("2048 \ n" + NUL) в массив размера 4 в стеке.Это перезапишет 3 байта того, что находится под ним в стеке, что в данном случае равно cpOut.Новое значение cpOut показывает вам следующее: первый байт неизменен 0x08, затем следующие 3 являются последними тремя байтами строки, которую вы пишете: 00 (NUL), 0a ('\ n'), 20 ('').

3 голосов
/ 18 ноября 2010

Я думаю, что это случай переполнения буфера.Попробуйте увеличить cOut, также замените sprintf на более безопасный snprintf:

sprintf(&cOut[0],"%d \n", number);

следует изменить на

snprintf(cOut,sizeof(cOut),"%d \n", number);
1 голос
/ 18 ноября 2010

эта строка:

sprintf(&cOut[0],"%d \n", number);

записывает 7 символов: «2048 \ n \ 0», но есть место только для 4 из них. Значение 0x8000a20 содержит (в обратном порядке): пробел, новую строку и символ 0.

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