问题描述
我有一些代码:
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
指向的堆中的内存是否空闲?
From the value of the pointer and the value on the memory where it pointed to, I think I can't know whether the bit of memory in the heap pointed by ip
is free?
我知道,如果要在代码后再次添加delete ip;
,编译器将抛出错误.这将很好地证明内存是空闲的.
I know that if I were to add delete ip;
again after my code, the compiler will throw an error. That will be a good evidence that the memory is free.
但是,我如何测试它是否和平释放,以便可以将其用作决定代码中进一步操作的条件?
But, how can I test whether it's free peacefully, so that I can use it as a condition to decide further operations in my code?
推荐答案
如果您的代码取决于特定内存是否空闲,则可能会遇到一些设计问题.但是,如果确实要测试,则可以重载operator new
和operator delete
(及其对应的数组/类版本),以便它们跟踪在程序可用的某些全局数据结构中分配了哪些内存位置.这是一些玩具示例(在ideone.com上运行),该示例定义了一个放置new
的位置,该位置可以跟踪哪些内存(和大小)已分配.
You probably have some design issues if your code depends on whether specific memory is free or not. But, if you indeed want to test, you can overload operator new
and operator delete
(and their corresponding array/class versions) so they keep track of which memory locations are allocated in some global data structure available to your program. Here is some toy example (live on ideone.com) which defines a placement new
that keeps track of what memory (and size) was allocated.
#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();
}
编辑:我意识到上面的代码可能存在一些问题.在功能
I realized that there may be some issues with the code above. In the function
void operator delete(void *p) noexcept
{
memory.erase(p);
free(p);
}
memory.erase(p)
也会调用operator delete
,因此您可能会遇到一些讨厌的递归(由于某种原因,上面的代码只输入了一次递归).解决方法是为使用malloc/free
而不是全局operator new/delete
的std::map memory
编写自定义分配器.
memory.erase(p)
calls also operator delete
, so you may end up with some nasty recursion (for some reason, the code above only enters the recursion once). A fix is to write a custom allocator for the std::map memory
that uses malloc/free
instead of global operator new/delete
.
这篇关于c ++如何测试堆中的某些内存是否空闲?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!