我的问题并非“Is it safe to `free()` memory allocated by `new`?”的重复。
我正在为POD编写一个玩具垃圾收集器,在其中定义了自己的自定义operator new/new[]
和operator delete/delete[]
。以下是代码:
#include <iostream>
#include <map>
std::map<void*, std::size_t> memory; // globally allocated memory map
struct collect_t {} collect; // tag for placement new
void* operator new(std::size_t size, const collect_t&)
{
void* addr = malloc(size);
memory[addr] = size;
return addr;
}
void* operator new[](std::size_t size, const collect_t&)
{
return operator new(size, collect);
}
void operator delete(void *p, const collect_t&) noexcept
{
memory.erase(p); // should call ::operator delete, no recursion
free(p);
}
void operator delete[](void *p, const collect_t&) noexcept
{
operator delete(p, collect);
}
void display_memory()
{
std::cout << "Allocated heap memory: " << std::endl;
for (auto && elem : memory)
{
std::cout << "\tADDR: " << elem.first << " "
<< "SIZE: " << elem.second << std::endl;
}
}
void clear()
{
for (auto && elem : memory)
free(elem.first); // is this safe for arrays?
memory.clear();
}
int main()
{
// use the garbage collector
char *c = new(collect) char;
int *p = new(collect) int[1024]; // true size: sizeof(int)*1024 + y (unknown overhead)
display_memory();
clear();
display_memory();
}
这个想法很简单:我用自定义的new
来分配内存并将所有已分配的跟踪地址存储在std::map
中,并确保在我的clear()
函数中清除所有内存。我为我的new
和delete
使用标签(不重载全局函数),以便std::map
的分配器可以调用全局函数而不会导致递归调用。我的问题是:在我的
clear()
函数中,我在这一行中释放内存for (auto && elem : memory)
free(elem.first); // is this safe for arrays?
对于数组,例如int *p = new(collect) int[1024];
,这种方法安全吗?我认为是安全的,因为void* operator new[](std::size_t size, const collect_t&)
调用了 operator new(size, collect);
,而后者又调用了malloc
。尽管如此,我并不100%确定,这种方法是否存在错误的可能性?
void*
中,而是自定义placement new。根据我对标准片段的阅读,传递的size_t
将包括所需的任何开销?通常对于placement new的关注点是在调用new[]
之前确定目标缓冲区大小,这可能会请求比缓冲区更多的内存。但是,我不确定如何处理对齐方式。简而言之:传递给new[]
的大小是请求的内存大小,而不是数组的大小。 - Yakk - Adam Nevraumontnew[]
的size_t
不包括该开销,我无法想象如何使new[]
有用。因此,我对你的说法持怀疑态度。我是否误解了你的说法?我错了吗?还是你错了? - Yakk - Adam Nevraumont