假设有20个内存块,指针p
指向第一个块。
现在,当我这样做时:
p++;
free(p);
将释放多少块内存以及为什么?
答案 0 :(得分:25)
取消确定性。不能说。您需要提供malloc()
返回的确切指针。
将指针free()
传递给malloc()
[和家人]的malloc()
是undefined behaviour。
根据您的问题,如果p
- ed指针存储在p++
中,您执行free(p);
并调用p
,那么calloc
不再是 malloc
,realloc
或c99
函数返回的指针 。
根据章节7.20.3.2,{{1}}标准,第2段
free函数导致ptr指向的空间被释放,即可用于进一步分配。如果ptr是空指针,则不执行任何操作。否则,如果参数与calloc,malloc或realloc函数先前返回的指针不匹配,或者如果通过调用free或realloc释放了空间,则行为未定义。
答案 1 :(得分:3)
使用malloc()
calloc()
或realloc()
在堆上分配内存后,会记录有关在任何这些调用期间分配的内存量的记录。
因此,如果分配了一些x
字节,则该信息由OS单独维护。
像
----------------------------
| Pointer | Memory allocated|
----------------------------
现在让你在动态内存分配期间使用的指针指向任何位置,即在初始分配期间指向的内存位置以外的某个位置。
但是当你调用free时它并不关心指针指向它的位置它只是查找记录,它获取信息在堆上动态分配了多少内存。
所以free()使用此记录并释放分配的内存,因此您始终需要传递malloc()
,calloc()
和realloc()
答案 2 :(得分:3)
这取决于。您的问题没有提供足够的信息。
如果p++
导致p
引用也由malloc()
分配的块,则该块将返回到堆(无论分配的大小)。但是,如果它不是指向动态分配块的指针,则会破坏堆,结果是非确定性的,但永远不会好!
例如,如果你这样做:
struct sBlock* p = malloc( 20 * sizeof(struct sBlock) ) ;
p++ ; // point to second block
free( p ) ; // Heap corruption or runtime error
不需要C运行时来捕获此类错误,但某些实现或调试环境可能会这样做。更常见的情况是,在您破坏堆用于跟踪内存的结构之后尝试分配或释放更多内存时,错误将被忽略。实际的故障模式将是不可预测的,并且在代码接近度和实际错误的时间内经常会发生一些距离 - 使调试变得困难。