当我运行以下代码时:
int main(int* argc, char** argv) {
int* array = malloc(5 * sizeof(int));
free(array + 3);
}
我得到错误pointer being freed was not allocated
。我的直觉是,free
不是试图释放array
的第四个元素,而是试图释放在其最后一个元素之后的3*sizeof(int)
字节。这是正确的吗?如果是这样,为什么会发生这种情况?执行该程序所产生的行为是否总是可预测的,还是未定义的或特定于实现的?
free
希望您使用从malloc
返回的相同地址,否则可能会发生任何事情。malloc
调用每次调用分配一个完整的段,在本例中为5int
大。释放这个段的一部分是没有意义的,这不是堆的工作方式。
实际上,在你的情况下,你传递了一个位于3*sizeof(int)
字节的地址到段的数据部分,这不是一个有效的地址,因为free需要malloc
使用的初始地址,以便知道该段的内部头从哪里开始。当您传递错误的地址给它时,它可能会抓取随机数据的其他部分并将其视为标头。行为未定义。
(然而,你可以传递一个空指针给free()
,这保证是一个无操作。)
From specifications offree()
:
简介
#include <stdlib.h> void free(void*ptr);
free
函数导致ptr
所指向的空间被释放,也就是说,可供进一步分配。如果ptr
是空指针,则不进行任何操作。否则,如果参数与之前由内存管理函数返回的指针不匹配,或者如果空间已经被调用free
或realloc
释放,则行为未定义。
因此,你要做的是未定义行为
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf
malloc
分配内存块。
您只能取消分配(free
)此块。不能释放单个元素或块的一部分。
你可以重新分配(realloc
)这个块,使它更大或更小。