我有一些代码:
int *ip = new int;
*ip = 42;
cout << *ip << endl;
cout << ip << endl;
delete ip;
cout << *ip << endl;
cout << ip << endl;
输出是:
42
0x100105400
42
0x100105400
从指针的值和它指向的内存上的值,我想我无法知道ip
指向的堆中的那 block 内存是否空闲?
我知道如果我在我的代码后再次添加 delete ip;
,编译器会抛出错误。这将是内存空闲的一个很好的证据。
但是,我怎样才能和平地测试它是否免费,以便我可以将它作为一个条件来决定我的代码中的进一步操作?
最佳答案
如果您的代码取决于特定内存是否空闲,您可能会遇到一些设计问题。但是,如果您确实想要测试,您可以重载 operator new
和 operator delete
(以及它们相应的数组/类版本),以便它们跟踪分配了哪些内存位置在您的程序可用的某些全局数据结构中。这是一些玩具示例 ( live on ideone.com ),它定义了一个位置 new
来跟踪分配的内存(和大小)。
#include <iostream>
#include <map>
std::map<void*, std::size_t> memory; // globally allocated memory map
struct tag {}; // tag for placement new's so we don't overload the global ones
void* operator new(std::size_t size, const tag&)
{
void* addr = malloc(size);
memory[addr] = size;
return addr;
}
void* operator new[](std::size_t size, const tag&) // for arrays
{
return operator new(size, tag());
}
void operator delete(void *p) noexcept
{
memory.erase(p);
free(p);
}
void operator delete[](void *p) noexcept // for arrays
{
operator delete(p);
}
void display_memory()
{
std::cout << "Allocated heap memory: " << std::endl;
for (auto && elem : memory)
{
std::cout << "\tADDR: " << elem.first << " "
<< "SIZE: " << elem.second << std::endl;
}
}
bool is_allocated(void* p)
{
return (memory.find(p) != memory.end());
}
int main()
{
int *p = new(tag()) int[10];
char *c = new(tag()) char;
// test if p is allocated
std::cout << std::boolalpha << "Allocated: "
<< is_allocated(p) << std::endl;
// display the allocated memory
display_memory();
// remove p
delete[] p;
// test again if p is allocated
std::cout << std::boolalpha << "Allocated: "
<< is_allocated(p) << std::endl;
display_memory();
// remove c
delete c;
display_memory();
}
编辑:我意识到上面的代码可能存在一些问题。在函数中
void operator delete(void *p) noexcept
{
memory.erase(p);
free(p);
}
memory.erase(p)
还调用了 operator delete
,因此您最终可能会遇到一些讨厌的递归(出于某种原因,上面的代码只进入递归一次).解决方法是为 std::map 内存
编写一个自定义分配器,它使用 malloc/free
而不是全局 operator new/delete
。
关于c++如何测试堆中的某一位内存是否空闲?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29820626/