15

I do this:

MyClass myObject = *new MyClass();

But a lot of people say I should do this:

MyClass *myObject = new MyClass();

Is there a performance difference. Or a logical reason to use the second method at all? I just prefer to use the first method to get rid of the pointer confusions.

Archie Mejia
  • 243
  • 1
  • 7
  • 25
    The question I have is "why do you do this?" If you want to drink a glass of water, do you first go buy a new glass, fill it with water, pour the water into an old glass and throw the new glass away? – Nik Bougalis Jun 02 '13 at 06:02
  • 2
    Wow... I'm shocked that anyone lets you get away with the first method. That's just Babytown frolicks. Nik's metaphor is spot on. – Iron Savior Jun 02 '13 at 06:05
  • 3
    If you've ever handed in homework that contained code like that you should seriously demand a refund. They obviously didn't catch it or were not effective in explaining what it does and why you shouldn't do it. – Captain Obvlious Jun 02 '13 at 06:09
  • 17
    @NikBougalis: good metaphor, but he's even worse: he doesn't throw the glass away; he forgets it somewhere on the table. I wonder how many glasses are in the house! – Emilio Garavaglia Jun 02 '13 at 07:04
  • If MyClass did not have a copy constructor, wouldn't RVO or copy elision prevent leaks? I'm not trying to advocate the '*new' practice - I'm just trying to explain why any leaks went unnoticed. – Jim Fred Jun 02 '13 at 07:07
  • 3
    @JimFred [RVO is only allowed to happen when the copy constructor is viable](http://stackoverflow.com/a/11209362/168175) – Flexo Jun 02 '13 at 08:00
  • Oh Java, how we all love your influence on programmers' minds... – leftaroundabout Jun 02 '13 at 09:00
  • @Flexo I tried on VC++ 11 and g++ and, in both cases, without a copy constructor, the C c = *new C() statement resulted in exactly 1 constructor and 1 destructor when c when out of scope. I'm puzzled why it worked so well. – Jim Fred Jun 02 '13 at 18:28
  • 1
    @JimFred: Because "without" a copy constructor, the compiler will generate one, and you didn't observe that compiler-generated copy ctor. – MSalters Jun 02 '13 at 22:54
  • 1
    possible duplicate of [Why does the use of 'new' cause memory leaks?](http://stackoverflow.com/questions/8839943/why-does-the-use-of-new-cause-memory-leaks) – R. Martinho Fernandes Nov 08 '13 at 09:40

3 Answers3

29

Both are not same!
First gives you a Undefined behavior[Ref 1:] or a memory leak while second doesn't if you call delete later.

MyClass myObject = *new MyClass();

Allocates a object of type MyClass on freestore and then copies that object to myObject. You lose the pointer to the dynanically allocated object and thus can never deallocate it.
If MyClass destructor has side effects and your program depends on those side effects then it gives you Undefined Behavior if not then what you have is a simple plain memory leak.

MyClass *myObject = new MyClass();

Allocates a object of type MyClass on freestore and the points myObject to the address where the dynamically allocated object is placed. You still have the pointer to the object, which you can deallocate by calling delete later on.


If your question is, what is the best way to do this,
The answer is to not use dynamically allocated object at all:

MyClass obj;

Good Read:

Why should C++ programmers minimize use of 'new'?


[Ref 1:]
C++11 Standard: 3.8.4:

A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly calling the destructor for an object of a class type with a non-trivial destructor. For an object of a class type with a non-trivial destructor, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released; however, if there is no explicit call to the destructor or if a delete-expression (5.3.5) is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.

Community
  • 1
  • 1
Alok Save
  • 190,255
  • 43
  • 403
  • 518
  • 5
    Why does letting go of a heap-allocated object with a side effect in the destructor produce undefined behaviour? – Alex B Jun 02 '13 at 05:21
  • http://stackoverflow.com/questions/1978709/are-memory-leaks-undefined-behavior-class-problem-in-c – Flexo Jun 02 '13 at 05:26
  • 2
    @AlexB: Because the standard explicitly says so. Added the quote for your reference. Also, it is quite intuitive behavior, say for example one closes file handles or descriptors in destructor which never gets called then a UB is definitely on. – Alok Save Jun 02 '13 at 05:36
  • 2
    It's only UB if the program _depends on_ the side-effects of the destructor, but that's really just a tautology. Just because a destructor might _have_ side-effects, if they are ignored then leaking memory is just leaking memory. – Lee Daniel Crocker Jun 02 '13 at 05:39
  • @Flexo: The Q you linked specifically asks if *Memory leaks cause Undefined Behavior* the accepted answer in a way is correct. No memory leaks don't cause UB. It is not calling `delete` on `new`ed pointer with the condition that destructor produces side effects which are used by the program further that causes UB. Maybe the answer needs a edit to detail this. – Alok Save Jun 02 '13 at 05:42
  • 1
    @LeeDanielCrocker: I have added the exact quote from the standard to specify that. It says it clear enough even my wordings may not have been as clear. – Alok Save Jun 02 '13 at 05:43
  • Well, I have to say I've never thought about this in terms of UB. That counts as learning something :) – chris Jun 02 '13 at 05:48
  • The citation clearly talks about "[ending] the lifetime of [an] object by reusing [its] storage". If you reuse the storage without destroying the object, then there's UB. However, this bears no relevance to the OP's snippet. There is no UB there. – avakar Jun 02 '13 at 15:35
  • @avakar: How does it not bear a relevance? The quote is clear enough, and everything said in the answer is well within boundaries of the standard. i am sorry if it is not intuitive enough for you, i cant explain it any better. – Alok Save Jun 02 '13 at 16:29
  • I find it clear too. There is no reusing of storage in the question, hence the paragraph you quoted doesn't apply. – avakar Jun 02 '13 at 19:58
24

The first example says: Allocate memory on the stack for an instance of MyObject, then allocate memory on the heap for another one, construct the one on the heap, copy its contents to the one on the stack, and then lose track of the heap pointer so it can't be freed.

The second one says: Allocate a pointer on the stack, allocate space for an instance of MyObject on the heap, construct it, and assign the pointer to its address so it can be freed later.

The second case uses less memory, is faster, and doesn't leak memory. The first case says "I don't understand C++".

Lee Daniel Crocker
  • 12,296
  • 1
  • 24
  • 47
5

The first is nonsense.

MyClass myObject = *new MyClass();

The part after the = allocates memory and creates a new MyClass object. The first part creates a new MyClass object by calling copy constructor with the RHS MyClass object. Then the memory allocated in the RHS leaks because you don't have a saved pointer to delete it with.

The above statement is the same as writing.

MyClass myObject;

Followed by

Leak memory equal to size of MyClass.

First of all decide whether you want an object on the stack or on the heap.

If you want an object on the stack, then do

MyClass myObject;

This creates a MyClass Object - it serves well for most purposes.

If you need an object on the heap, then do

MyClass *myObject = new MyClass();

The first way - allocating on the stack is more efficient. You do heap allocation for other reasons

  1. At compile time, you don't know how many objects you need to create.
  2. Use classes polymorphically.
user93353
  • 12,985
  • 7
  • 50
  • 106
  • 1
    It's not the same - there's a requirement for the copy constructor to at least be visible and it may get called, where as `MyClass myObject;` is always just default constructed. – Flexo Jun 02 '13 at 05:23
  • I want to edit and change "nonsense" (it compiles, it does something, and there'll be some crackhead somewhere who actually designs a system that somehow requires you to do something exactly like this, probably a network guy) to "priceless", "comedy gold", "retardarific", "herptastic". – kfsone Jun 02 '13 at 05:34
  • 1
    I think nonsense is too strong, but I wouldn't call it funny (or similar words) either. It may be "correctly" using a badly-designed class, but in the usual case, it leaks memory and wasn't what was intended. If it was intended, you'd at least want a good explanatory comment there too. – mwfearnley Jun 02 '13 at 05:39
  • Is it okay to use `MyClass& myObject = *new MyClass();` as long as I use `delete &myObject` later in the program? – John Militer Jun 14 '18 at 15:02