内存分配器:避免两次空闲内存

时间:2014-04-04 18:43:27

标签: c memory-management

我正在实现一个内存分配器。我目前遇到了这个问题

void deallocate(void* ptr) {
   // code to deallocate memory start at ptr
}

// client test code
printf("Test : deallocate same pointer two times \n");
char* ptr = (char*) allocate(32);
deallocate(ptr);
deallocate(ptr); // ERROR

因为deallocate(无论如何),只是在指针ptr释放内存。 ptr中的地址存储仍然像以前一样,我不能将它设置为NULL(因为参数是指针,而不是指针的指针)。

所以我的问题是:如何防止分配相同的指针两次,如上面的场景?

谢谢:)

3 个答案:

答案 0 :(得分:2)

分配器不会阻止这种情况。它不是分配器的责任,而是分配器用户,负责双重删除。

如果您真的希望解除分配器具有这种防呆机制,则需要在分配器实现中的全局变量中存储所有已分配指针的表。然后,deallocator将首先检查指针是否已注册,如果是,则取消分配并从表中删除指针。当然,您需要一个非常有效的容器用于表格,插入,删除和查找的复杂性很低。

答案 1 :(得分:1)

如果您想阻止一个解决方案是跟踪已传递到您的free版本的所有地址:调用free时,首先要检查ptr是否已经过ptr传递给你(例如通过在地图/哈希表中搜索该键)。如果它存在,你什么都不做;否则你将ptr的条目放入数据结构中,然后继续做你需要做的任何事情。

当然,它并不那么简单:在进行分配时,还需要从数据结构中删除size。如果您在地址addr分配ptr字节,那么您需要删除addr <= ptr <= addr+size {{1}}。

假设您正在实施任何类型的敏感内存管理器,您将已经维护一个空闲池(未分配或已分配并已释放的块列表),甚至可能是链接列表已分配的块。

在这种情况下,您可以简单地遍历空闲池以查看正在释放的块是否已在空闲池中列出,如果已经列出,则不执行任何操作。或者,或者,迭代已分配块的列表,并确保您被要求释放的内容确实已分配。

当然,正如其他人已经注意到的那样,这通常是调用者而不是分配器的责任,尽管在分配器中具有这种功能对于调试目的很有用。

答案 2 :(得分:0)

一旦释放内存,NULL指针,如果在NULL指针上调用free,就不会有异常,

像,

deallocate(ptr);
ptr = NULL; 
deallocate(ptr); // NO ERROR