sprintf的使用方法有误?

3
我有一个简单的测试程序。
#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个回答

7

由于字符串"2048 \n"无法适应char cOut[4];,因此会发生缓冲区溢出。


4
您正在将7个字节("2048 \n" + NUL)写入大小为4的栈数组中。这将覆盖下面栈中的3个字节,本例中是cpOut。新值cpOut表明:第一个字节未更改0x08,接下来三个字节是您正在写入的字符串的最后三个字节:00(NUL),0a('\ n'),20(' ')。

3
我觉得这是缓冲区溢出的情况。尝试将cOut变量增大,并用更安全的snprintf替换sprintf函数:
sprintf(&cOut[0],"%d \n", number);

应该被更改为

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

1

这一行:

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

写入7个字符:"2048 \n\0",但只有4个字符的空间。值0x8000a20包含(倒序):空格、换行符和字符0。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接