奇怪的内存泄漏由C++中的新建/删除
Strange Memory leak by new/delete in C++
以下是我的问题和代码:
- 当代码运行到第 26 行时,此过程获得的内存不返回操作系统?
- 但是,如果我删除第 16 行,内存会正确释放吗?
我知道这不是使用这么多小内存块的常规方法,但我非常想知道原因。
我已经用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、分配内存并停止,检查内存分辨率:
可容纳 2.9G 内存
2、释放内存并停止,检查内存分辨率:
可容纳 2.9G 内存
C++没有垃圾回收,因此保留指针的额外副本不会阻止内存被解除分配。
delete[] ptr[i]
之后发生的事情是,地图上充满了无法再使用的悬空指针。
另一个想法:您可能会看到内存泄漏,因为tMap
还分配动态内存来存储插入的数据。当地图超出范围时,即第 27 行之后,该内存将被释放。
1、当代码运行到26行时,此进程获得的内存不返回操作系统?
不能保证任何内存会由C++程序释放到操作系统,因为它被程序正确delete
。 在许多C++运行时中,删除的动态分配内存仍将保留供同一程序将来使用,而不会发布到操作系统。 GCC/Linux 是编译器/运行时环境的一个例子,其中较大的分配通常在共享内存段中完成,这些内存段可以在程序终止之前发布到操作系统,以便操作系统或其他程序可以使用它们。
2、但是,如果我删除第16行,内存是否正确释放?
第 16 行对以后删除/释放第 22 行的内存没有任何影响(这可能会将其返回到应用程序稍后可能重新分配的动态内存池中,或者如上所述实际将其释放到操作系统)。 不过,它确实涉及对std::map
元素本身的更多动态分配。
请注意,tMap
析构函数本身不会以任何方式delete
或释放内存。 要通过类似指针的变量或其容器自动释放内存,请使用智能指针,例如std::shared_ptr
或std::unique_ptr
(您可以谷歌它们以获取信息)。
- 创建模板类型而不新建/删除
- C++ 分配器:运算符新建或放置新
- C++ 在请求特定字节的新建后删除
- 为什么非放置"新建"和"删除"内置于语言中,而不仅仅是常规函数?
- 来自C#的mingw DLL:为什么我必须覆盖新建/删除?
- 复制构造函数、赋值运算符、新建
- C++ - 定义自定义新建和删除运算符时make_shared
- 使用安全零内存新建/删除时出现问题
- 奇怪的内存泄漏由C++中的新建/删除
- CRT 检测到应用程序在堆缓冲区(新建/删除)类结束后写入内存
- 无法覆盖C++中纯抽象类中的运算符删除/新建
- 这种模式是什么意思?新建(&条目[num_entries])项目;
- 编译器或标准C++库 - 新建和删除
- 分配新建的shared_ptr
- 在 std::shared_ptr<> 中新建之前的预期标识符
- 混合运算符和表达式新建/删除
- 新建和删除的经验法则
- 如何新建value_type指针
- 运算符新建和删除重载作用域
- 使用运算符重载(新建/删除)实现单例的优缺点