Free Memory Occupied by Std List, Vector, Map etc

12,366

Solution 1

No: if objects are not allocated with new, they need not be freed/deleted explicitly. When they go out of scope, they are deallocated automatically. When that happens, the destructor is called, which should deallocate all objects that they refer to. (This is called Resource Acquisition Is Initialization, or RAII, and standard classes such as std::list and std::vector follow this pattern.)

If you do use new, then you should either use a smart pointer (scoped_ptr) or explicitly call delete. The best place to call delete is in a destructor (for reasons of exception safety), though smart pointers should be preferred whenever possible.

Solution 2

What I can say in general is that the C++ standard containers make copies of your object under the scenes. You have no control over that. What this means is that if construction of your objects (Point_2 in your case) involves any resource allocations (eg: new or malloc calls), then you have to write custom versions of the copy constructors and destructors that make this behave sensibly when your map decides to copy Point_2s around. Usually this involves techniques like reference counting.

Many people find it much easier to just put pointers to complex object into standard containers, rather than the objects themselves.

If you don't do anything special in constructors or destructors for your objects (which now appears to be the case for you), the there's no problem whatsoever. Some containers (like maps) will be doing dynamic allocations under the scenes, but that is effectively invisible to you. The containers worry about their resource allocations. You only have to worry about yours.

Share:
12,366
Graviton
Author by

Graviton

A software developer.

Updated on June 08, 2022

Comments

  • Graviton
    Graviton almost 2 years

    Coming from a C# background, I have only vaguest idea on memory management on C++-- all I know is that I would have to free the memory manually. As a result my C++ code is written in such a way that objects of the type std::vector, std::list, std::map are freely instantiated, used, but not freed.

    I didn't realize this point until I am almost done with my programs, now my code is consisted of the following kinds of patterns:

    struct Point_2
    {
        double x;
        double y;
    };
    
    struct Point_3
    {
        double x;
        double y;
        double z;
    };
    
    list<list<Point_2>> Computation::ComputationJob
        (list<Point_3>pts3D, vector<Point_2>vectors)
    {
        map<Point_2, double> pt2DMap=ConstructPointMap(pts3D);
        vector<Point_2> vectorList = ConstructVectors(vectors);
        list<list<Point_2>> faceList2D=ConstructPoints(vectorList , pt2DMap);
        return faceList2D;
    }
    

    My question is, must I free every.single.one of the list usage ( in the above example, this means that I would have to free pt2DMap, vectorList and faceList2D)? That would be very tedious! I might just as well rewrite my Computation class so that it is less prone to memory leak.

    Any idea how to fix this?

  • Graviton
    Graviton over 13 years
    @larsmans, so you are saying that I don't have to deal with the deallocation of memory for std::list and all?
  • T.E.D.
    T.E.D. over 13 years
    Due to all the copying, there are some situations where simple RAII can be a bit of a disaster when combined with the C++ containers.
  • Fred Foo
    Fred Foo over 13 years
    Only if you, as T.E.D. says, use new in class Point_2, you need to worry about allocation and deallocation. The standard containers handle memory allocation internally. (Read about RAII, it's useful in avoiding the drudgeries of manual memory management.)
  • Fred Foo
    Fred Foo over 13 years
    @T.E.D.: that's where smart pointers such as shared_ptr come in.
  • Graviton
    Graviton over 13 years
    question updated. Not too sure what you mean, I don't need to use new or malloc to allocate memory for both Point_2 and Point_3, as shown in the above code, so i guess that means that I don't need any custom code for memory management.
  • T.E.D.
    T.E.D. over 13 years
    @Graviton - You don't. However, you do have to deal with the fact that map is liable to be making copies of the object you give it. If the default constructor and destructor for your object are complex, this may be a non-trivial issue for you.
  • T.E.D.
    T.E.D. over 13 years
    Agreed. With those (often called POD s or Plain Old Data types), you can use STL containers with abandon without having to worry about dynamic allocations.
  • stonemetal
    stonemetal over 13 years
    @Graviton to repeat the most important part of the answer. If you call new you must call delete. The only time you need to care about explicitly cleaning up memory is when you explicitly allocate memory. Now another thing to be aware of is that it causes errors to deallocate the same memory twice.
  • etarion
    etarion over 13 years
    If you do use new, then you should explicitly call delete. The best way to do so is in a destructor (for reasons of exception safety). I strongly disagree with that. If you do use new, put it into a smart pointer like boost::scoped_ptr would be far better, and avoids all sorts of issues that can occur when using raw pointers, like deallocating the same thing twice like stonemetal mentioned.
  • T.E.D.
    T.E.D. over 13 years
    Edited "std" to "stl", as STD has some other unfortunate connotations in English. Revert if you like. I do agree that if all std containers cleaned up their contents automatically, the world would be a much better place. :-)
  • EA304GT
    EA304GT about 5 years
    Underrated comment is underrated