以下是了解未定义行为的程序。 我正在为ptr分配10 * 4 = 40字节的内存并且我正在尝试访问,所以当完成*(ptr + 0x100)超过40个字节时它必须给我一个seg错误。从代码中观察到的是,它在*(ptr + 0xc000)处给出了seg错误。当它超出堆的大小时,它是否会给出seg错误?当ptr试图访问ptr + 100时,为什么它没有给我一个seg错误,这超出了分配给它的40个字节的边界。
#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");
}
答案 0 :(得分:1)
写入超出有效malloc位置的堆会导致未定义的行为。它可能会也可能不会导致seg故障。取决于堆位置中的内容以及程序其余部分的使用方式。
您的计划可能根本不会失败。但它最终会破坏堆,如果你的程序更长,你会看到问题。很难找到问题。
答案 1 :(得分:1)
如您所知,您的程序会调用 undefined 行为。 未定义并不意味着“在任何情况下都保证会出现段错误”; undefined 表示“符合C编译器的实现可以输出执行任何操作的程序”。
答案 2 :(得分:0)
不要试图理解未定义的行为,调用它未定义的全部意义在于明确任何可能发生。
事实上,UB最烦人的方面是它有时会起作用。至少如果它一直失败,那么整个类别的错误永远不会到达现场。
试图理解UB就像试图了解猫(或一些前女友)。你可能想你已经对它进行了排序,但随后它们会打开你: - )
而不是理解,你应该简单地避免。