开发者

Releasing memory from map. C++

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");

The problem is: "delete mp" doesn't do anything. To compare:

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");

releases memory. How开发者_运维问答 to release memory from map?

PS: p("string") just pauses program and waits for input.


The RAM used by the application is not a precise way to tell if the memory has been semantically freed.

Freed memory is memory that you can reuse. Sometimes though, you don't observe this freed memory directly in what the OS reports as memory used by our app.

You know that the memory is freed because the semantics of the language say so.


Actually, if the following code doesn't leak:

{
  std::map<int, int> some_map;
}

The following code shouldn't leak as well:

{
  std::map<int, int>* some_map = new std::map<int, int>();
  /* some instructions that do not throw or exit the function */
  delete some_map;
}

This applies whatever the type you use with new, as long as the type is well written. And std::map is probably very well written.

I suggest you use valgrind to check for your leaks. I highly doubt that what you observed was a real leak.


As Daniel mentions, RAM used by an application is not necessarily an indicator of a memory leak. With respect to the behavior you notice regarding vectors, a vector guarantees that the memory layout is contiguous & hence when you create a vector of size 99999999, all the 99999999 elements are laid out in sequence & would constitute a pretty sizable chunk of memory. Deleting this would definitely impact process size. A map behaves differently (as per Wikipedia, its often implemented as a self balancing binary tree) so I guess deleting it causes fragmentation in the process memory space & maybe due to that the process memory does not drop immediately. The best way to detect memory leaks would be to use a tool like valgrind which will clearly indicate whats wrong.


To pinpoint if you are releasing memory or not, try adding observable effects to the destructors of your object and... observe them. For instance, instead of a map, create a custom class which emits output when the destructor is invoked. Something like this:

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

You will witness that deleting the pointer invokes the destructor of your objects, as expected.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜