堆中断(未初始化段的末尾)附近存储了什么?

What is stored near the heap-break (end of uninitialized segment)?

在这个简单的代码中:

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

int main(){
    void * first = sbrk(4096);
    void *p = sbrk(0);

    //sigterm, however were it (p-4) -> it could be derefenced
    *((int*)(p-3)) = 1;
    printf("%d\n",*(int*)(p-3));
}

如果我试图在堆末尾附近取消引用地址,我会遇到段错误。但是 B-16(其中 B 代表堆中断)是可取消引用的,而 B-12 不是(段错误)。那么堆的中断附近存储了哪些信息?

你不是在做 p-12 和 p-16,你在做 p-3 和 p-4。

你正在做 (int*)(p-3) 即你正在减去 3 然后 然后 转换为 int,而不是相反 ((int*)p)-3。因此,编译器减去声明指向的任何类型 p 的 3 个,而不是 3 个整数。

该类型是 void,因为 pvoid*。所以编译器减去 3 个字节。然后你读取 4 个字节,因为 int 在你的编译器上是 4 个字节。

注意:void* 中减去是一个特定于 GCC 的扩展 - 一个不属于普通 C 的额外功能。一些编译器会给你一个错误,说你不能添加或减去 void* 指针。在那些编译器上,要减去 3 个字节,您必须强制转换为 char* 然后减去 3.