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