【问题标题】:Does free function given in p188 at K&R actually free memory that was allocated before?K&R 的 p188 中给出的 free 函数是否实际上释放了之前分配的内存?
【发布时间】:2018-07-16 15:17:09
【问题描述】:

让我们看看这个给定的代码:

void free(void *ap) {
Header *bp, *p;

bp = (Header *)ap - 1;
for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)
    if (p >= p->s.ptr && (bp > p || bp < p->s.ptr))
        break;
if (bp + bp->s.size == p->s.ptr) {
    bp->s.size += p->s.ptr->s.size;
    bp->s.ptr = p->s.ptr->s.ptr;
} else
    bp->s.ptr = p->s.ptr;
if (p + p->s.size == bp) {
    p->s.size += bp->s.size;
    p->s.ptr = bp->s.ptr;
} else
    p->s.ptr = bp;
freep = p;
}

据我所知,如果这个给定的 free 得到一个指向已经存在的内存块的指针,这个循环:

for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)
    if (p >= p->s.ptr && (bp > p || bp < p->s.ptr))
        break;

实际上将永远存在。 因为当 p==ap 并且对于每个其他 p 条件:!(bp > p && bp s.ptr) 将是真的 并且条件 p >= p->s.ptr && (bp > p || bp s.ptr) 将为假。

编辑: 完整的代码可以在这里看到: Explain this implementation of malloc from the K&R book

【问题讨论】:

  • 什么是Headerfreep 是什么? s 是什么?请出示minimal reproducible example
  • 顺便说一句:我不确定从一本 30 年前的书中学习 C 是否真的是个好主意。
  • @MichaelWalz:我愿意。恕我直言,它仍然是 C 的最佳展示。确实,那么您应该继续深造。
  • 分配器假设以前分配的块将来可能有用是很正常的。所以不,它不会释放内存,它可以用于将来的 malloc() 调用。更复杂的分配器也将与操作系统合作以释放地址空间,通常是在足够的连续空间再次可用时,但依赖于操作系统实现肯定不是代码的重点。

标签: c malloc free


【解决方案1】:

由于freep 是空闲列表(顾名思义),ap 是已分配的卡盘(因此它不在空闲列表中),p==ap 不应该是真的。 循环结束下列条件之一为真:

  • 要释放的块位于当前和下一个具有更高地址的空闲列表元素之间(循环条件);
  • 要在空闲列表末尾(最高地址)释放的块,即空闲列表所在的位置。 (如果有条件)。

【讨论】:

  • 所以实际上你同意我的观点,即给定的空闲函数在获得一个时不会释放分配的内存(当 ap 在空闲列表中时)?我问这个问题是因为免费函数的名称具有误导性。
  • 函数释放分配的内存。分配的内存是空闲列表中的内存。当您尝试释放已在空闲列表中的内存时,您会遇到麻烦。
猜你喜欢
  • 2014-03-07
  • 1970-01-01
  • 2012-07-29
  • 1970-01-01
  • 2022-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多