这里我有一个非常简单的程序,输出对我来说很奇怪,
#include "stdio.h"
#include "string.h"
void func_stack();
int main(int argc, char *argv[]) {
func_stack();
}
void func_stack() {
int a = -1;
char s[4];
int b = -1;
strcpy(s,"1234");
printf("a+b result to %d\n",a+b);
}
我猜strcpy函数使用'\ 0'覆盖了以后的int变量“b”的东西,并给出一个奇怪的计算结果,但是我在x86 linux机器上编译后,我仍然得到-2作为结果,它是结果与没有strcpy相同。
任何人都可以解释为什么会发生这种情况?
答案 0 :(得分:3)
C字符串以NUL终止。当您使用strcpy()
将"1234"
复制到s
时,实际上会复制五个字节,包括NUL终结符。然后,您正在超出s
数组的范围进行编写,因此正在调用未定义的行为。
运行此操作时发生的实际取决于您的CPU架构和编译器(以及编译器选项,优化等)。
答案 1 :(得分:2)
将数组大小更改为+ 1
例如:
"you"
所以数组大小为3 + 1>> char s [4];
所以对你的代码
"1234"
数组大小为4 + 1>> char s [5];
1个最后一个字节用于NULL
作为字符串的结尾。
CMIIW
答案 2 :(得分:0)
您的strcpy
正在尝试复制5个字符。即1234\0
成4个字符的数组。这就是为什么你正在观察这种行为,因为它覆盖了堆栈上的东西。
答案 3 :(得分:0)
正如Greg所说,你正在调用未定义的行为,因此任何事情都可能发生。你正在使用64位机器吗?如果是这样,变量可能是字对齐的,因此s
在整数之前有额外的4个字节的填充。
答案 4 :(得分:0)
因为你做a = b = -1,所以它们中的所有位都应该是1。 使用调试器或printf,您可以通过检查
的地址来检查s [4]的'\ 0'的写入位置&s[4],
((char*)&a) and ((char*)&a)+(sizeof(int)-1),
((char*)&b) and ((char*)&b)+(sizeof(int)-1)
如果&的地址b不与s [0] .. s [4]重叠,那么你将得到结果-2。