期待它时没有出现分段错误

时间:2011-07-09 09:35:46

标签: c segmentation-fault undefined-behavior

我正在玩缓冲区溢出,但我对在Mac OS上运行以下简单C程序时发现的内容感到困惑。

#include <stdio.h>

int main(void) {

        char buf[2];

        scanf("%s", buf);

        printf("%s\n", buf);

}

通过将buf的长度设置为2个字节,我预计在输入字符串“CCC”时会导致分段错误,但这不会发生。只有在输入长度为24个字符的字符串时才会出现分段错误。

发生了什么事?它与字符编码有关吗?

感谢。

5 个答案:

答案 0 :(得分:5)

一旦溢出缓冲区,程序的行为就不会被定义。任何事情都可能发生。你无法预测它。

在缓冲区之后可能会或可能不会有一些填充字节,这对您的代码执行来说并不重要。你不能依赖它。一个不同的编译器,编译为32位与64位,调试设置......所有这些都可能会在溢出后改变代码执行。

答案 1 :(得分:2)

因为buf在堆栈上。当你开始覆盖它时,你开始覆盖属于OS将不会捕获的程序的堆栈,这取决于在那里分配的其他内容(例如,编译器创建的寄存器的溢出槽)。只有当您跨越分配的堆栈边界时,操作系统才有机会引发段错误。

答案 2 :(得分:1)

猜测它与内存布局有关。如果你的进程可以访问你所覆盖的内容(页面映射writable),操作系统就没有机会看到你做错了什么。

确实,在做这样的事情时,从C程序员的眼中“这是完全错误的!”。但是在操作系统的眼中“好吧,他正在写一些页面的东西。页面是否映射了足够的权限?如果是,OKAY”。

答案 3 :(得分:1)

无法保证您完全会出现分段错误。 char buf[2]覆盖之后有更多数据可能会或可能不会导致分段错误。

答案 4 :(得分:1)

buf是在堆栈上分配的,你只是覆盖了一个没有使用的区域,很有可能没有人会抱怨它。在某些平台上,您的代码将接受整个段落。