以下是我的问题和代码:
我知道这不是使用这么多小内存块的常规方法,但我很想知道原因。
我用MALLOC_MMAP_MAX_=1000000 MALLOC_MMAP_THRESHOLD_=1024,
运行了这个程序,但没有任何改变。
int i = 0;
std::cout << "waitting for input, you can check current memory" << std::endl;
std::cin >> i;
char** ptr = new char *[1000000];
std::map<int, char *> tMap;
for (unsigned long i = 0; i < 1000000; i ++)
{
ptr[i] = new char[3000];
tMap.insert(make_pair(i, ptr[i])); //line 16
}
std::cout << "waitting for input, you can check current memory" << std::endl;
std::cin >> i;
for (unsigned long i = 0; i < 1000000; i ++)
{
delete []ptr[i];
}
delete []ptr;
std::cout << "waitting for input, you can check current memory" << std::endl;
std::cin >> i; //line 26
return 0;
这里有更多材料,我已经检查了tMap的内存,小于100M。
1,分配内存并停止,检查内存res:
2,解除分配内存并停止,检查内存res:
答案 0 :(得分:3)
C ++没有垃圾收集,因此保留指针的额外副本并不会阻止内存被释放。
delete[] ptr[i]
之后发生的事情是地图上到处都是无法再使用的悬空指针。
另一个想法:您可能看到的内存泄漏事实是tMap
还分配动态内存来存储插入的数据。当地图超出范围时,将在第27行之后释放该内存。
答案 1 :(得分:2)
1,当代码运行到第26行时,通过此过程获得的内存不会返回OS?
无法保证C ++程序将任何内存释放到操作系统只是因为程序正确delete
。在许多C ++运行时中,已删除的动态分配内存仍将保留供将来使用由同一程序,而不会释放到操作系统。 GCC / Linux是编译器/运行时环境的一个示例,其中较大的分配通常在共享内存段中完成,可以在程序终止之前释放到操作系统,例如操作系统或其他程序可以使用它们。
2,但是,如果我删除行:16,内存将被正确释放?
第16行对第22行的内存的后续删除/释放没有任何影响(可能会将其返回到应用程序稍后可能重新分配的动态内存池,或者实际将其释放到OS正如刚才提到的)。它确实涉及std::map
元素本身的更多动态分配。
请注意tMap
析构函数本身不是delete
或以任何方式释放内存。要使内存自动释放 - 通过类似指针的变量或容器 - 使用智能指针,例如std::shared_ptr
或std::unique_ptr
(您可以将它们谷歌获取信息)。