奇怪的内存泄漏由C++中的新建/删除

Strange Memory leak by new/delete in C++

本文关键字:新建 C++ 删除 内存 泄漏      更新时间:2023-10-16

以下是我的问题和代码:

  1. 当代码运行到第 26 行时,此过程获得的内存不返回操作系统?
  2. 但是,如果我删除第 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_ptrstd::unique_ptr(您可以谷歌它们以获取信息)。