返回后的分段错误?

时间:2014-05-02 16:35:27

标签: c

我在返回执行后得到Segmentation fault。为什么它会在返回之后而不是strcpy?

int main()
{

     char a[2];

     strcpy(a,"0123456789101112131415161718192021222324252627282930");
     printf("%s\n",a);

     return 0;

}

4 个答案:

答案 0 :(得分:4)

  

返回执行后我收到Segmentation fault。为什么它会在返回之后而不是strcpy?

你犯了一个名为a buffer overflow的常见错误。这会导致未定义的行为,这是一个标准答案。但是,如果您了解典型计算机如何使用a stack,则可以了解返回时崩溃的原因。大多数CPU使用向下病房增长堆栈。所以在你调用strcpy之前,堆栈就像是,

sp + 0 : a[0]
sp + 1 : a[1]
sp + 2 : padding
sp + 3 : padding
sp + 4: return address (four bytes)

每次在'C'中使用函数时,编译器机制都会创建call frame。返回地址作为 stack 的一部分存在,其中编译器为a[]数组分配空间。由于字符串副本的大小不足,因此会覆盖返回地址。您返回前不会使用此值。返回地址将被值0x34353637覆盖,这是ASCII文本'4567'的二进制指针。

建议使用something like strncpyan alternative。例如,

strncpy(a,"012345678...", sizeof(a));
a[sizeof(a)-1] = 0;   /* ensure the string is terminated. */

如果你想要打印完整的字符串,显然你需要增加'a'数组的大小。

答案 1 :(得分:3)

  

为什么它会在返回之后而不是strcpy?

main返回时,您会收到分段错误,因为您在main函数的堆栈帧中覆盖了关键数据(保存的帧指针和返回地址),而不是strcpy的堆栈帧中功能。

正如其他人已经说过的那样,你会调用未定义的行为,任何事情都可能发生:从无到有,再到核战争。

答案 2 :(得分:1)

您正在尝试将包含2个以上字符的字符串加载到仅包含2个字符的char数组中。这将导致分段错误,因为您正在覆盖为char数组分配的内存,这也可能导致未定义的行为。

答案 3 :(得分:0)

你的程序覆盖了缓冲区,这会导致未定义的行为,这意味着任何事情都可能发生。