我在返回执行后得到Segmentation fault
。为什么它会在返回之后而不是strcpy?
int main()
{
char a[2];
strcpy(a,"0123456789101112131415161718192021222324252627282930");
printf("%s\n",a);
return 0;
}
答案 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 strncpy或an 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)
你的程序覆盖了缓冲区,这会导致未定义的行为,这意味着任何事情都可能发生。