sprintf的错误用法?

时间:2010-11-18 15:42:17

标签: c++ c printf

我有简单的测试程序

#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

有人可以解释一下为什么通过调用sprintf函数来覆盖指针cpOut吗?

4 个答案:

答案 0 :(得分:6)

因为字符串"2048 \n"不适合char cOut[4];,所以您正在创建缓冲区溢出。

答案 1 :(得分:4)

您正在将7个字节(“2048 \ n”+ NUL)写入堆栈中大小为4的数组中。这将覆盖堆栈下面3个字节的任何内容,在本例中为cpOutcpOut的新值向您显示:第一个字节未更改0x08,然后接下来的3个是您正在写入的字符串的最后三个字节:00(NUL),0a('\ n'), 20('')。

答案 2 :(得分:3)

我认为这是缓冲区溢出的情况。尝试使cOut更大,也用更安全的snprintf替换sprintf:

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

应改为

snprintf(cOut,sizeof(cOut),"%d \n", number);

答案 3 :(得分:1)

这一行:

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

写入7个字符:&#34; 2048 \ n \ 0&#34;,但只有4个字符有空格。值0x8000a20包含(以相反顺序):空格,换行符和字符0。