Free Memory Occupied by Std List, Vector, Map etc
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_2
s 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.
Comments
-
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
andfaceList2D
)? That would be very tedious! I might just as well rewrite myComputation
class so that it is less prone to memory leak.Any idea how to fix this?
-
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. over 13 yearsDue 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 over 13 yearsOnly if you, as T.E.D. says, use
new
inclass 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 over 13 years@T.E.D.: that's where smart pointers such as
shared_ptr
come in. -
Graviton over 13 yearsquestion updated. Not too sure what you mean, I don't need to use
new
ormalloc
to allocate memory for bothPoint_2
andPoint_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. 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. over 13 yearsAgreed. 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 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 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. over 13 yearsEdited "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 about 5 yearsUnderrated comment is underrated