【问题标题】:strange program output for strcpystrcpy 的奇怪程序输出
【发布时间】:2012-05-09 04:22:13
【问题描述】:

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

#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 发生的结果相同。

谁能解释为什么会这样?

【问题讨论】:

    标签: c


    【解决方案1】:

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

    当你运行它时实际会发生什么,这取决于你的 CPU 架构和你的编译器(以及编译器选项、优化等)。

    【讨论】:

    • 我在sparc机器上编译过,结果也是-2,
    • 如果您想知道确切在任何给定机器上会发生什么,编译它然后查看生成的汇编代码。只有这样才能确定。
    【解决方案2】:

    将数组大小更改为 + 1

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

    所以你的代码 "1234"数组大小为4+1 >> char s[5];

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

    CMIIW

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

          因为你在做 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。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-02-16
            • 1970-01-01
            • 2021-07-13
            • 2014-02-04
            • 2020-05-14
            • 2013-10-04
            • 2015-09-27
            • 1970-01-01
            相关资源
            最近更新 更多