C语言 堆断点(未初始化段的结束)附近存储了什么?



在这个简单的代码中:

#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("%dn",*(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个int型。

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

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

相关内容

最新更新