-6

下面是一个了解未定义行为的程序。我正在为 ptr 分配 10 *4 = 40 字节的内存并且我正在尝试访问,所以它必须在完成 *(ptr+0x100) 时给我一个超过 40 字节的段错误。从代码中观察到的是,它在 *(ptr+0xc000) 处给了我段错误。当它超出堆的大小时,它会给出段错误吗?为什么当 ptr 尝试访问超出分配给它的 40 个字节边界的 ptr+100 时它没有给我一个 seg 错误。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

main()
{
        int * ptr = malloc(10 * sizeof(int) );

        *ptr = 0x100;
        printf(" Done 1\n");

        *(ptr+0x9) = 0x90;
        printf(" Done 2\n");

        *(ptr+0x100) = 0x400;
        printf(" Done 3\n");

        *(ptr + 0x1000) = 0x4000;
        printf(" Done 4\n");

        *(ptr + 0x4000) = 0x4000;
        printf(" Done 5\n");

        *(ptr + 0x8000) = 0x8000;
        printf(" Done 6\n");

        *(ptr + 0xc000) = 0xc000;
        printf(" Done 7\n");
}
4

3 回答 3

1

写入超出有效 malloc 位置的堆会导致未定义的行为。它可能会或可能不会导致段错误。取决于堆位置中的内容以及程序其余部分如何使用它。

您的程序可能根本不会失败。但它最终会破坏堆,如果你的程序更长,你会看到问题。很难发现问题。

于 2013-09-11T03:21:24.517 回答
1

如您所知,您的程序会调用未定义的行为。未定义并不意味着“保证在所有情况下都发生段错误”;undefined的意思是“一个符合 C 编译器的实现可以输出一个可以做任何事情的程序”。

于 2013-09-11T03:25:47.437 回答
0

不要试图理解未定义的行为,将其称为未定义的全部意义在于表明任何事情都可能发生。

事实上,UB 最烦人的地方是它有时会起作用。至少如果它一直失败,那么一整类错误将永远不会出现在该领域。

试图了解 UB 就像试图了解猫(或一些前女友)。你可能认为你已经把它整理好了,但他们会打开你:-)

与其理解,不如简单地避免。

于 2013-09-11T03:26:52.997 回答