2

Possible Duplicate:
Why does the use of ‘new’ cause memory leaks?

I'm fairly new to STL, and I've read that it is good practice to generally keep vectors of objects rather than vectors of pointers to objects. In an attempt to comply with that creed I ran into the following scenario:

//Approach A
//dynamically allocates mem for DD_DungeonRoom object, returns a pointer to the block.
//then, presumably, copy-constructs the de-referenced DD_DungeonRoom as a 
//disparate DD_DungeonRoom object to be stored at the tail of the vector
//Probably causes memory leak due to the dynamically allocated mem block not being
//caught and explicitly deleted
mvLayoutArray.push_back(*(new DD_DungeonRoom()));

//Approach B
//same as A, but implemented in such a way that the dynamically allocated mem block
//tempRoom can be deleted after it is de-referenced and a disparate DD_DungeonRoom is
//copy-constructed into the vector
//obviously rather wasteful but should produce the vector of object values we want
DD_DungeonRoom* tempRoom = new DD_DungeonRoom();
mvLayoutArray.push_back(*(tempRoom));
delete tempRoom;

first question: In Approach A, is a memory leak created?
second question: assuming A does produce a memory leak, does B solve it? third question: is there (or more likely, 'what is') a better way to add custom class objects (e.g. requiring dynamic allocation via 'new' or 'malloc') to a vector by value?

thanks, CCJ

Community
  • 1
  • 1
CCJ
  • 1,619
  • 26
  • 41

3 Answers3

8

first question: In Approach A, is a memory leak created?

Yes.

second question: assuming A does produce a memory leak, does B solve it?

Yes, but it's a silly solution. And unsafe in the event that the DD_DungeonRoom's copy constructor or vector::push_back throws an exception.

third question: is there (or more likely, 'what is') a better way to add custom class objects (e.g. requiring dynamic allocation via 'new' or 'malloc') to a vector by value?

No objects in C++ require dynamic memory allocation. Just add objects directly to the vector calling the constructor, sans new.

mvLayoutArray.push_back(DD_DungeonRoom());

Even better, if your compiler supports the feature (it is new to C++11), would be to use emplace_back which completely bypasses any copies, and constructs your object directly in the vector. Just pass the same arguments to it as you would to your constructor. In our case, that's none:

myLayoutArray.emplace_back();
Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
2

Approach A causes a leak, yes. Approach B doesn't, but since all you do is allocate an object on the heap, put a copy into the vector and then delete it, you could in that case just as well do:

DD_DungeonRoom tempRoom;
mvLayoutArray.push_back(tempRoom);

Optionally you could do a block around it to make the local variable go out of scope if you want the destructor to run right afterwards.

Also, it you are curious if something will leak memory, there are lots of good tools to actually try it out and see what happens. valgrind is one example that is super easy to use.

Mattias Nilsson
  • 3,639
  • 1
  • 22
  • 29
1

if your only problem with aproch A is the memory leak, why not use a vector of shared_ptr?

qPCR4vir
  • 3,521
  • 1
  • 22
  • 32
  • 1
    Because it has overhead that is unnecessary for his situation. – Benjamin Lindley Jan 09 '13 at 18:56
  • More overhead than constructing each only to be copied into the vector and then be destroyed? it depend on the size or cost of constructing DD_DungeonRoom. or? – qPCR4vir Jan 09 '13 at 19:05
  • shared_ptr does add a little more complexity than I think I need at the moment; obviously Approach B is not a good production solution, but rather serves to clarify my confusion. @BenjaminLindley 's suggestion is best for my situation. – CCJ Jan 09 '13 at 19:29
  • OK. Now I'm not sure, but chekc if you can benefised by the move-copy construcotr or soo. – qPCR4vir Jan 09 '13 at 19:43