C ++中new / delete导致奇怪的内存泄漏

时间:2018-02-02 10:05:32

标签: c++ memory-leaks

以下是我的问题和代码:

  1. 当代码运行到第26行时,通过此过程获得的内存不会返回到OS?
  2. 但是,如果删除第16行,内存将正确释放?
  3. 我知道这不是使用这么多小内存块的常规方法,但我很想知道原因。

    我用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:

    holds 2.9G memory

    2,解除分配内存并停止,检查内存res:

    holds 2.9G memory

2 个答案:

答案 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_ptrstd::unique_ptr(您可以将它们谷歌获取信息)。