代码之家  ›  专栏  ›  技术社区  ›  foret

从地图中释放内存。C++

  •  3
  • foret  · 技术社区  · 16 年前
    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”)只是暂停程序并等待输入。

    4 回复  |  直到 16 年前
        1
  •  9
  •   Daniel Daranas    16 年前

    应用程序使用的RAM不是一种精确的方法来判断内存是否已被语义释放。

    释放的内存是可以重用的内存。不过,有时候,在操作系统报告的应用程序使用的内存中,您不会直接观察到释放的内存。

    您知道内存是释放的,因为语言的语义是这样说的。

        2
  •  2
  •   ereOn    16 年前

    实际上,如果以下代码没有泄漏:

    {
      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 检查有无泄漏。我非常怀疑你所观察到的 真实的 泄漏。

        3
  •  2
  •   Raam    16 年前

    正如Daniel提到的,应用程序使用的RAM不一定是内存泄漏的指示器。 关于您注意到的向量行为,向量保证内存布局是连续的,因此,当您创建大小为99999999的向量时,所有99999999元素将按顺序排列,并将构成相当大的内存块。删除这肯定会影响进程大小。一个映射的行为不同(根据维基百科,它通常被实现为一个自平衡的二叉树),所以我猜删除它会导致进程内存空间中的碎片,也许是因为进程内存不会立即下降。 检测内存泄漏的最佳方法是使用Valgrind这样的工具,它可以清楚地指示出哪里出了问题。

        4
  •  1
  •   Francesco larlin    16 年前

    为了确定你是否在释放内存,试着在你的对象的析构函数中添加可观察的效果…观察他们。 例如,创建自定义类而不是映射,该类在调用析构函数时发出输出。 像这样:

    #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;
    }
    

    您将看到删除指针会像预期的那样调用对象的析构函数。