0

I am currently having an issue related to:

vector<myObj> myVector;

Q1. Please tell me the difference between the following two lines:

a) myVector.push_back(*new myObj());
b) myVector.push_back(myObj());

NOTE: I realise that line a) is bad practice as it is causing a memory leak by allocating the myObj's contents dynamically before copying it into the vector and therefore can't be freed...

However, I was under the assumption that both of these lines should result in the vector containing the exact same contents, though it appears that this assumption is incorrect. The software I am currently developing RUNS fine using line a) (I know, I know this is causing a leak, please try to disregard this just for now) but crashes with various different exc_bad_access errors on line b).

Q2. can anyone explain why this might be?

EDIT: When posting this I originally assumed that my issue must be related to some difference in the resulting vector contents, however my problem was actually related to fulfilling the "Rule of Three" http://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming) Thank you to @WhozCraig , @juanchopanza & @Alex Antonov for your help!

trincot
  • 317,000
  • 35
  • 244
  • 286
mindTree
  • 916
  • 9
  • 18
  • 6
    `*new myObj()` I present to you the memory leak operator. – Borgleader Jan 25 '14 at 08:33
  • 1
    Please show the definition of `myObj`. – CB Bailey Jan 25 '14 at 08:41
  • 1
    If it doesn't crash with (a), but does with (b), somewhere in `myObj` you're likely not fulfilling the [Rule of Three](http://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)). I'd almost bet on it. – WhozCraig Jan 25 '14 at 08:42
  • Sorry about the wait @WhozCraig! Will this out asap and let you know if it helps! Thanks a lot for the suggestion! – mindTree Jan 25 '14 at 09:00

3 Answers3

4

what is the difference...

The difference is line a) causes a memory leak, and line b) doesn't. This is because the dynamically allocated object in a) is immediately discarded, and there is no handle to call delete on it. The vector holds and owns its elements, which in this case are copies of what you push back into it.

The software I am currently developing runs fine using line a) but crashes with various different exc_bad_access errors on line b).

It may appear to run fine, but it has a resource leak. So it is not fine by any stretch of the imagination. If you have a problem with line b) it may be because myObj manages resources and does not follow the rule of three. Line b) should work fine for a well designed class.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • He already knows that. Also, (a) works but (b) doesn't – Rohit Chatterjee Jan 25 '14 at 08:38
  • 1
    @RohitChatterjee he claims to know it, but doesn't seem to really know it, judging from the text and the claim that is "works". Also, a) cannot possibly "work", it may just appear to do so. – juanchopanza Jan 25 '14 at 08:41
  • @juanchopanza As mentioned, I'm aware that there is a leak and that this is NOT OK. Please try to disregard this for just a moment. I am primarily concerned with the difference in the the resulting vector contents. – mindTree Jan 25 '14 at 08:47
  • 1
    @mindTree Yet you ask for the difference between the two lines. So I am telling you the difference. Would it make it better if I added an "as you already know..." to it? – juanchopanza Jan 25 '14 at 08:48
  • @juanchopanza, the very next line following the two lines of code explains that I understand the leak issue, so clearly I am looking for a different "difference". – mindTree Jan 25 '14 at 08:50
  • 1
    @mindTree there is no difference, besides the memory leak (unless you have overloaded `new` for `myObj`). That is what my answer it telling you. You have broken code, undefined behaviour, and that can manifest itself in all sorts of weird ways) – juanchopanza Jan 25 '14 at 08:52
  • 3
    @mindTree does the links both juan and I provided not work ? Think about what is *not* done with (b) but is with (a). Namely two objects are created (the one in the `new` expression and the one in the vector by-copy), but only one destructor is fired because of the leak. You can likely conclude that when both destructors fire, chaos ensues. Therefore, I submit to you you're shallow-copying dynamic allocation in `myObj`'s copy-constructor, and breaking the Rule of Three in the process. *Read that article*. We're not magicians, without source for `myObj` as requested, speculation is what u get. – WhozCraig Jan 25 '14 at 08:56
  • 1
    And now he downvotes... wonderful... –  Jan 25 '14 at 08:58
  • Thank you @juanchopanza! All I wanted to know is if there was any other difference besides the leak, as stated in the original question. – mindTree Jan 25 '14 at 08:58
  • @H2CO3 I think it takes more rep to down-vote, so it can't be OP. I must have annoyed someone else :) – juanchopanza Jan 25 '14 at 09:05
  • @WhozCraig thanks so much for that detailed suggestion! That's exactly what I was looking for! I'd happily up your comments however my "rep's" being reduced as apparently my question wasn't clear enough. Sorry for any confusion, your help is greatly appreciated! – mindTree Jan 25 '14 at 09:07
  • @juanchopanza either way, it's too bad. :( –  Jan 25 '14 at 09:13
  • No clue why this got downvoted =/ – Borgleader Jan 25 '14 at 09:33
2

In line a) you're creating 2 objects and you have the following method calls:
1) Default constructor for first object
2) Copy constructor for second object

In line b) you're creating 2 objects as well but you have the following method calls:
1) Default constructor for first object
2) Copy constructor for second object
3) Destructor for first object

So obviously the line a) works because the destructor is not called. It implies that most probably in line b) you're deallocating/freeing some resource (e.g. a dynamically allocated memory) in destructor and then trying to access that resource by the second object. In that case you need to implement the copy constructor properly. E.g. you need to allocate new memory/object in copy constructor instead of simply copying a pointer to memory/object.

Alex Antonov
  • 942
  • 5
  • 9
0

A1: The difference is that (a) creates an object on the heap and then dereferences it, and (b) creates a stack object.

A2: Since you need to also delete heap allocted objects you will get a memory leak. std::vector does not do this for you, since it can't know whether the passed object is allocated on the heap or the stack.

When inserting objects to an vector, it will be copied. If you want to keep heap allocated objects, you need to define it as such:

std::vector<*myObj> myVector;
qstebom
  • 719
  • 4
  • 12
  • Thanks for your reply qstebom, I am aware of this. However, I am primarily concerned with what the difference is in the resulting vector contents? – mindTree Jan 25 '14 at 08:49
  • The std::vector<*myObj> looks like a typo –  Jan 25 '14 at 08:51
  • Also, use "dynamic vs automatic allocation" instead of "stack vs heap". "The stack" and "the heap" are implementation details and are irrelevant when describing abstract behavior. They might not even exist. –  Jan 25 '14 at 08:59
  • Thanks @H2CO3 ! I'll edit the question and keep this in mind from now on! – mindTree Jan 25 '14 at 09:39
  • myObj wasn't a typo from my side. :) – qstebom Jan 25 '14 at 13:02