130

Possible Duplicate:
What is difference between instantiating an object using new vs. without

This is probably a basic question, and might have already been asked (say, here); yet I still don't understand it. So, let me ask it.

Consider the following C++ class:

class Obj{
    char* str;
public:
    Obj(char* s){
        str = s;
        cout << str;
    }
    ~Obj(){
        cout << "Done!\n";
        delete str;        // See the comment of "Loki Astari" below on why this line of code is bad practice
    }
};

what's the difference between the following code snippets:

Obj o1 ("Hi\n");

and

Obj* o2 = new Obj("Hi\n");

Why the former calls the destructor, but the latter doesn't (without explicit call to delete)?

Which one is preferred?

Sadeq Dousti
  • 3,346
  • 6
  • 35
  • 53
  • 5
    Which C++ text book are you using? And have you looked at the "related" questions over there =======>>>>>> –  Jun 13 '11 at 22:48
  • 5
    Both are borken as they try and delete a pointer they do not own. You can not delete a pointe that was retrieved from `"Hi there"` – Martin York Jun 13 '11 at 22:53
  • 2
    Even if they owned the pointers, the class itself would still be broken due to deleting the pointer in the destructor, but having compiler generated copy constructor and assignment operator (violation of the rule of the three). So any copy of the class would mean two objects trying to delete the same pointer – Grizzly Jun 13 '11 at 23:09
  • 3
    I hope you mean `delete` instead of `destroy` (which doesn't exist). – Christian Rau Jun 13 '11 at 23:19
  • Hasn't been mentioned yet, but `o1` may either have static or automatic duration, depending on whereabouts in the program this line occurs. – M.M Oct 11 '16 at 08:24

2 Answers2

150

Both do different things.

The first creates an object with automatic storage duration. It is created, used, and then goes out of scope when the current block ({ ... }) ends. It's the simplest way to create an object, and is just the same as when you write int x = 0;

The second creates an object with dynamic storage duration and allows two things:

  • Fine control over the lifetime of the object, since it does not go out of scope automatically; you must destroy it explicitly using the keyword delete;

  • Creating arrays with a size known only at runtime, since the object creation occurs at runtime. (I won't go into the specifics of allocating dynamic arrays here.)

Neither is preferred; it depends on what you're doing as to which is most appropriate.

Use the former unless you need to use the latter.

Your C++ book should cover this pretty well. If you don't have one, go no further until you have bought and read, several times, one of these.


Your original code is broken, as it deletes a char array that it did not new. In fact, nothing newd the C-style string; it came from a string literal. deleteing that is an error (albeit one that will not generate a compilation error, but instead unpredictable behaviour at runtime).

Usually an object should not have the responsibility of deleteing anything that it didn't itself new. This behaviour should be well-documented. In this case, the rule is being completely broken.

starball
  • 20,030
  • 7
  • 43
  • 238
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 31
    "Automatic storage duration" is colloquially known as "on the stack", (since this storage is usually part of the thread's function call stack, and is discarded when the function exits) and "dynamic storage duration" is colloquially known as "on the heap". – Mike DeSimone Jun 13 '11 at 23:00
  • 5
    @Mike: Yes, and I despise those terms with an astronomical passion. It's quite deliberate that I did not employ them; I'm the last person that you'll ever see propagating those inaccurate phrases. – Lightness Races in Orbit Jun 13 '11 at 23:01
  • 1
    @Mike: (Still, I understand that it may be useful for the OP to be aware of the connection; so, thanks for that.) – Lightness Races in Orbit Jun 13 '11 at 23:02
  • 1
    I posted them because they're in the vernacular and Sadeq's going to see them. That's all. I don't care for them either, but I use both since I usually have to document embedded systems, where you really do need to know if something is on the stack or not. – Mike DeSimone Jun 13 '11 at 23:05
  • 1
    @LightnessRacesinOrbit Would you please elaborate why "on the stack" is not accurate? – Yichuan Wang Feb 24 '14 at 03:25
  • 3
    @YichuanWang: C++, like every other programming language, is an _abstraction_. When you are rationalising about a piece of C++ code, it is helpful to do so within the context of that abstraction. Tying your reasoning to some specific implementation (say, a computer with an x86-compatible CPU) is needlessly restrictive and leads to a lack of rigour/provability within the scope of the rules defined by the C++ standard. The C++ standard gives rules about _storage duration_, not about some hypothetical data structure in memory that is where those objects live. – Lightness Races in Orbit Jun 17 '14 at 08:57
  • @YichuanWang: _(cont.)_ Speaking more practically, it leads people to _get it wrong_ when you have code like `struct T { int x; }; T* p = new T();` Is `p->x` "on the stack"? No, but many would say "yes". If I asked instead whether it had "automatic storage duration" then you'd be more inclined to spot that the answer is still no. – Lightness Races in Orbit Jun 17 '14 at 08:58
  • **since the object creation occurs at runtime**, meaning? Does using `new` ensure that object creation occurs at runtime? If so, then when does the object creation happen when `new` is not used? – SexyBeast Jan 07 '15 at 21:57
  • @Cupidvogel: Yes. Without `new`, the code generated by your compiler has space for the object baked into it. Remember, assembly is not very like C++: the fact that your object exists is largely noticeable in the executable only by the fact that various pieces of arithmetic are aware of the existence of an object at a particular "location" within a stack frame. The object's existence is essentially "hard-coded" by default. – Lightness Races in Orbit Jan 07 '15 at 22:28
  • @LightnessRacesinOrbit I appreciate that this answer is 4 years old, but the link "one of these" [http://jcatki.no-ip.org/fncpp/Resources] in the answer is now broken, which is a shame because I was quite keen on buying one of your recommendations! – Jon Sep 07 '15 at 10:42
  • 4
    @Jon I guess [this](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) is the go-to list now. – Lightness Races in Orbit Sep 07 '15 at 11:54
29

The first allocates an object with automatic storage duration, which means it will be destructed automatically upon exit from the scope in which it is defined.

The second allocates an object with dynamic storage duration, which means it will not be destructed until you explicitly use delete to do so.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111