std::map<int, int> * mp = new std::map<int, int>;
for(int i = 0; i < 999999; i++){
mp->insert(std::pair<int, int>(i, 999999-i ));
}
p("created");
//mp->clear(); - doesn't help either
delete mp;
p("freed");
问题是:“删除mp”没有做任何事情。比较:
std::vector<int> * vc = new std::vector<int>;
for(int i = 0; i < 9999999; i++){
vc->push_back(i);
}
p("created");
delete vc;
p("freed");
释放记忆。如何从地图中释放记忆?
PS:p(“string”)只是暂停程序并等待输入。
答案 0 :(得分:9)
应用程序使用的RAM不是判断内存是否已被语义释放的精确方法。
释放内存是可以重用的内存。但有时候,您不会直接在操作系统报告的应用程序使用的内存中观察到这个释放的内存。
你知道内存被释放了,因为语言的语义是这样说的。
答案 1 :(得分:2)
实际上,如果以下代码没有泄漏:
{
std::map<int, int> some_map;
}
以下代码也不应泄漏:
{
std::map<int, int>* some_map = new std::map<int, int>();
/* some instructions that do not throw or exit the function */
delete some_map;
}
只要类型写得很好,这适用于new
使用的任何类型。 std::map
可能写得非常好。
我建议您使用valgrind
来检查您的泄漏情况。我非常怀疑你观察到的是真正的泄漏。
答案 2 :(得分:2)
正如Daniel所提到的,应用程序使用的RAM不一定是内存泄漏的指标。 关于向量注意到的行为,向量可以保证内存布局是连续的&amp;因此,当您创建一个大小为99999999的向量时,所有99999999元素按顺序排列&amp;将构成相当大的记忆。删除这肯定会影响流程大小。地图的行为不同(根据维基百科,它通常实现为自平衡二叉树),所以我想删除它会导致进程内存空间中的碎片。也许是因为进程内存不会立即丢失。 检测内存泄漏的最佳方法是使用像valgrind这样的工具,它会清楚地表明什么是错误的。
答案 3 :(得分:1)
要确定您是否正在释放内存,请尝试将可观察的效果添加到对象的析构函数中并观察它们。 例如,创建一个自定义类,而不是映射,该类在调用析构函数时发出输出。 像这样:
#include <map>
#include <iostream>
#include <utility>
class Dtor{
int counter;
public:
explicit Dtor(int c):counter(c) {std::cout << "Constructing counter: " << counter << std::endl; }
Dtor(const Dtor& d):counter(d.counter) {std::cout << "Copy Constructing counter: " << counter << std::endl; }
~Dtor(){ std::cout << "Destroying counter: " << counter << std::endl; }
};
int main(){
std::map<int, const Dtor&> * mp = new std::map<int, const Dtor&>;
for (int i = 0; i < 10; ++i){
mp -> insert(std::make_pair(i, Dtor(i)));
}
delete mp;
return 0;
}
您将看到删除指针会按预期调用对象的析构函数。