为什么 strcpy 没有分段错误?
可能的重复:
未定义、未指定和实现定义的行为
这应该会出现错误。为什么不呢。
#include <string.h>
#include <stdio.h>
char str1[] = "Sample string. Sample string. Sample string. Sample string. Sample string. ";
char str2[2];
int main ()
{
strcpy (str2,str1);
printf("%s\n", str2);
return 0;
}
我使用 gcc 版本 4.4.3 和以下命令:
gcc -std=c99 testString.c -o test
我还尝试将优化设置为 o (-O0)。
Possible Duplicate:
Undefined, unspecified and implementation-defined behavior
This should seg fault. Why doesn't it.
#include <string.h>
#include <stdio.h>
char str1[] = "Sample string. Sample string. Sample string. Sample string. Sample string. ";
char str2[2];
int main ()
{
strcpy (str2,str1);
printf("%s\n", str2);
return 0;
}
I am using gcc version 4.4.3 with the following command:
gcc -std=c99 testString.c -o test
I also tried setting optimisation to o (-O0).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
没有理由它“应该”出现段错误。代码的行为未定义。这并不意味着它一定会崩溃。
There's no reason it "should" segfault. The behaviour of the code is undefined. This does not mean it necessarily has to crash.
仅当您执行操作系统知道您不应该执行的内存访问时,才会发生分段错误。
因此,可能发生的情况是,操作系统以页为单位分配内存(通常约为 4KiB)。
str2
可能与str1
位于同一页面上,并且您没有运行到页面末尾,因此操作系统不会注意到。这就是未定义行为的问题。任何事情都可能发生。现在,该程序实际上可以在您的计算机上“运行”。明天,
str2
可能会被放在页面的末尾,然后出现段错误。或者,您可能会覆盖内存中的其他内容,并产生完全不可预测的结果。编辑:如何导致段错误:
两种方式。一个仍然是未定义的行为,另一个则不是。
或者以定义的方式执行此操作:
编辑:第三种和第四种分段错误方法
这是使用 strcpy 的第一种方法的变体:
并且此变体仅在使用
-O0
时对我来说崩溃:A segmentation fault only occurs when you perform an access to memory the operating system knows you're not supposed to.
So, what's likely going on, is that the OS allocates memory in pages (which are typically around 4KiB).
str2
is probably on the same page asstr1
, and you're not running off the end of the page, so the OS doesn't notice.That's the thing about undefined behavior. Anything can happen. Right now, that program actually "works" on your machine. Tomorrow,
str2
may be put at the end of a page, and then segfault. Or possibly, you'll overwrite something else in memory, and have completely unpredictable results.edit: how to cause a segfault:
Two ways. One is still undefined behavior, the other is not.
Or to do it in a defined way:
edit: third and fourth way to segfault
Here is a variation of the first method using strcpy:
And this variant only crashes for me with
-O0
:您的程序写入超出了分配的数组范围,这会导致未定义的行为。
该程序格式错误,可能会崩溃,也可能不会。可能会也可能不会做出解释。
它可能不会崩溃,因为它会覆盖一些超出数组边界但未使用的内存,但一旦该内存的合法所有者尝试访问它,它就会崩溃。
Your program writes beyond the allocated bounds of the array, this results in Undefined Behavior.
The program is ill-formed and It might crash or may not.An explanation may or may not be possible.
It probably doesn't crash because it overwrites some memory beyond the array bounds which is not being used, bt it will once the rightful owner of that memory tries to access it.
段错误是不有保证的行为。
这是做坏事的一个可能(有时很可能)的结果。
另一种可能的结果是纯粹靠运气。
第三种可能的结果是鼻恶魔。
A seg-fault is NOT guaranteed behavior.
It is one possible (and sometimes likely) outcome of doing something bad.
Another possible outcome is that it works by pure luck.
A third possible outcome is nasal demons.
如果你真的想知道这可能会破坏什么,我建议你看看被覆盖的内存之后会生成一个链接器映射文件,这应该会给你一个公平的想法,但这一切都取决于内存中的布局方式,甚至可以尝试使用 gdb 运行它来解释为什么它会出现或不会出现段错误,也就是说,访问冲突(硬件辅助)中内置检查的粒度不能比页面更精细,除非加入了一些软件魔法(即使使用本页粒度访问检查可能发生的情况是下一页确实指向您正在执行的程序的其他内容并且它是一个可写页面),了解 valgrind 的人可以解释它如何能够检测到此类访问违规(还有 libefence ),很可能(我的解释可能非常错误,如果我错了,请纠正我!)它使用某种形式的标记或比较来检查是否发生了越界访问。
if you really want to find out what this might be corrupting i would suggest you see what follows the over-written memory generate a linker map file that should give you a fair idea but then again this all depends on how things are layed out in memory, even can try running this with gdb to reason why it does or does not segfault, that being said, the granularity for built checks in access violations (HW assisted) cannot be finer than a page unless some software magic is thrown in (even with this page granularity access checking it may happen that the immediately next page does really point to something else for the program which you are executing and that it is a Writable page), someone who knows about valgrind can explain how it is able to detect such access violations (also libefence), most likely (i might be very wrong with this explanation, Correct me if i am wrong!) it uses some form of markers or comparisons for checking if out of bounds access has happened.