0

这里我有一个非常简单的程序,输出对我来说很奇怪,

#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 发生。

任何人都可以解释为什么会这样?

4

5 回答 5

3

C 字符串以 NUL 结尾。当您使用strcpy()to copy "1234"tos时,实际上复制了五个字节,包括 NUL 终止符。然后,您将超出s数组的范围进行写入,因此正在调用未定义的行为

运行它时实际发生的情况取决于您的 CPU 架构和编译器(以及编译器选项、优化等)。

于 2012-05-09T04:23:20.153 回答
2

将数组大小更改为 + 1

例如: "you"所以数组大小是 3+1 >> char s[4];

因此,对于您的代码 "1234",数组大小为 4+1 >> char s[5];

最后一个字节用作NULL字符串的结尾。

CMIIW

于 2012-05-09T04:29:21.983 回答
0

strcpy正在尝试复制 5 个字符。即成1234\04个字符的数组。这就是为什么您正在观察这种行为,因为它正在覆盖堆栈上的某些内容。

于 2012-05-09T04:30:19.700 回答
0

正如格雷格所说,您正在调用未定义的行为,因此任何事情都可能发生。您正在使用的机器是 64 位的吗?如果是这样,则变量可能是字对齐的,因此s在整数之前有额外的 4 个字节的填充。

于 2012-05-09T04:30:58.660 回答
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)

如果 a & b 的地址不与 s[0] .. s[4] 重叠,那么您将得到结果 -2。

于 2012-05-09T04:33:51.340 回答