2

What is the difference between

Kwadrat* k1 = new Kwadrat(1,2,3);
k1->field = 0;
Kwadrat k2(1,2,3);
k2.field = 0;

The first one is the pointer to the allocated memory, the second one is the object(where is it, on system stack?) why the second is worse? When we use first, whend the second one?

Marc B
  • 356,200
  • 43
  • 426
  • 500
Yoda
  • 17,363
  • 67
  • 204
  • 344
  • 1
    "why the second is worse?" -- who said it is? Ignore them. –  Aug 10 '12 at 15:56
  • 1
    The answer is "heap" (new) vs "stack". "Better" or "worse" is meaningless. Use "stack" when you want the object to go away when you leave scope; use "new" when the object needs to persist outside of the function it was created in. – paulsm4 Aug 10 '12 at 15:59
  • 1
    Usually you want to use the second version actually, unless you really need an objects livespan to exceed it's scope. – Cubic Aug 10 '12 at 15:59

4 Answers4

2

Dynamic allocation on the heap (uses new):
Kwadrat* k1 = new Kwadrat(1,2,3);
Object creation on the stack (without new):
Kwadrat k2(1,2,3);

Check out this Stack Overflow question for extended discussion about the stack and heap. Brian R. Bondy's answer does a nice job of comparing the two, while Jeff Hill's answer gives you some more nitty gritty details.

For a dangerously small summary:

  • you must delete objects you create with new, or else your code will suffer from memory leaks
  • you don't have to worry about manually deleting objects created on the stack because C++ Resource Allocation is Initialization (RAII) takes care of that for you
  • The stack can overflow if you attempt very large allocations.
  • As for which one you should use, that depends on the intended scope of the object you are creating
Community
  • 1
  • 1
Prashant Kumar
  • 20,069
  • 14
  • 47
  • 63
2

Using new dynamically creates an object on the heap meaning it will persist even if the pointer (k1*) goes out of scope.

This can be handy, but if it goes out of scope and you don't keep a copy of the pointer around it is permanently lost and causes a memory leak. This means you will lose the space used by that resource as long as the program executes. This is the downside of dynamically allocating memory with new, you have to track it and manually free it with the delete operator which takes extra work.

Doing it the other way creates a stack object which will be destroyed once it leaves scope, which is usually preferable.

Often when using dynamic memory creation with new, people work to gain this stack-like functionality by wrapping the dynamically created object in another object which will destroy it when it goes out of scope. This pattern is called Resource Acquisition is Initialization (RAII). This is most useful with reference counting so your objects can still be persisted out of scope, but will be destroyed when nothing refers to them any longer.

John Humphreys
  • 37,047
  • 37
  • 155
  • 255
0

new allocates an object on the heap. Your second example allocates memory on the stack. As soon as the function where you allocate k2 returns the memory won't be valid anymore (the destructor of k2 will of course be called first). You need to use new if you want the object to live longer than the function that creates it.

Yexo
  • 1,865
  • 15
  • 21
0

new lets you specify the storage for the allocation you request. allocations via new/new[] are generally on the heap (e.g. wrapping malloc), but ultimately implementation defined. as well, the compiler could have enough information to bypass this in some cases.

where is it, on system stack?

Technically, you would typically write C++ to the specification -- of an abstract machine.

But typically, yes - the object is allocated on the thread's stack.

Why the second is worse? When we use first, when the second one?

The second should be your default because it is very clear, the compiler manages its lifetime and allocation for you, and also very fast. Some exceptions to this include:

  • when you have a large allocation (stack sizes are relatively small)
  • sometimes when you want to share the allocation with another thread
  • when you want to pass the allocation to another thread
  • when you want the object to live beyond the scope of the method, and you will typically use a smart pointer or other container which will delete the object properly.

in short, there's a lot less that could go wrong (using the second), and far less time is spent creating allocations via the general purpose system allocators.

justin
  • 104,054
  • 14
  • 179
  • 226
  • Does `new` actually wrap `malloc` in the real world? I honestly don't know, but I see no reason it should use `malloc` rather than also using whatever platform-specific function is used to implement `malloc`. –  Aug 10 '12 at 15:59
  • yeah - new/new[] can call `malloc()`. C++ implementations can vary greatly by platform/architecture. – justin Aug 10 '12 at 16:01
  • 1
    @delnan - Justin is correctly stating that you can change "new" if you don't like the default allocation mechanism. And of course the C++ operator "new" is much more than just memory allocation - it also invokes the object's constructor. – paulsm4 Aug 10 '12 at 16:01
  • I didn't mean to question this answer, it just reminded me don't actually know how common implementations of `new` allocate memory. Also, I'm stupid and read "e.g." as "i.e.". –  Aug 10 '12 at 16:03
  • using malloc is the reference general purpose implementation for these types of allocators (at this level). of course, improvements and specializations could be made -- therefore, the reason the language offers you the ability to customize it extensively. – justin Aug 10 '12 at 16:09