这是我写的代码,
char *foo();
void main()
{
char *str=foo();
strcpy(str,"Holy sweet moses! I blew my stack!!");
printf("%s",str);
}
char * foo()
{
char str[256];
return str;
}
Run Code Online (Sandbox Code Playgroud)
当我在函数foo()中使用char数组时,main()函数中的strcpy不会将字符串复制到str中.但是,当我在函数foo()中使用int数组时,main()strcpy成功复制.
即
int str[256]; //in function foo
Run Code Online (Sandbox Code Playgroud)
产量
Holy sweet moses! I blew my stack!!
Run Code Online (Sandbox Code Playgroud)
如果
char str[256]; //in foo()
Run Code Online (Sandbox Code Playgroud)
输出:没事!
你正在做什么显然是UNDEF,但是..让我们试着理解为什么它适用于整数而不是字符..
TL; DR:printf使用堆栈,覆盖str指向的一些空间,但由于int数组在内存中比char数组大,所以它在堆栈中"遥遥领先"并且不会被覆盖.
int是4个字节,因此256个int将是1024个字节.
如果数组在堆栈中,这将指向RBP - 1024.
对于字符,char为1字节,256字符为256字节.
如果数组在堆栈中,这将指向RBP - 256.
这是什么意思?当foo返回时,str指针将指向当前堆栈指针"前面"的1024或256字节.
所以..当你调用strcpy(str,"yourstring"); 内存可能会被strcpy和printf使用的堆栈覆盖.这里的事情是它被覆盖但不是所有的堆栈,只是一点点,但足以覆盖256个字节,因此,该函数可以覆盖复制的字符串,这不会发生在你的int数组,因为字符串将在堆栈指针之前复制1024位,strcpy和printf不要使用这么多堆栈.
让我告诉你堆栈将如何结束:

如果更改char数组的大小,它可能会起作用.
所有这些都是未定义的行为,完全取决于您的架构,计算机和编译器.我目前正在使用Linux x86_64.