Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between these two object instantiation approaches?

Tags:

c++

Suppose I have a class named A:

Class A
{
...
}

And what's the difference between the following 2 approaches to instanciate an object:

void main(void)
{
    A a;  // 1
    A *pa=new A();  // 2
}

As my current understanding (not sure about this yet):

  • Approach 1 allocate the object a on the stack frame of the main() method, and so this object cannot deleted because that deletion doesn't make sense (don't know why yet, could someone explain that?).

  • Approach 2 allocate the object a on the heap of the process and also a A* vairable pa on the stack frame of the main() method, so the object can be deleted and and the pa can be assigned null after the deletion.

Am I right? If my understanding is correct, could someone tell me why i cannot delete the a object from the stack in approach 1?

Many thanks...

like image 371
smwikipedia Avatar asked Feb 22 '10 07:02

smwikipedia


People also ask

What is the difference between instantiation and initialization of an object?

A variable is initialized with a value. An object is instantiated when memory is allocated for it and it's constructor has been run. In the preceding line of code, the obj variable is initialized with the reference to the new Object that was instantiated.

What is the difference between instantiation and initialization of an object Java?

Declaration: The code set in bold are all variable declarations that associate a variable name with an object type. Instantiation: The new keyword is a Java operator that creates the object. Initialization: The new operator is followed by a call to a constructor, which initializes the new object.

What does it mean to instantiate an object in C++?

Instantiation is when a new instance of the class is created (an object). In C++ when an class is instantiated memory is allocated for the object and the classes constructor is run. In C++ we can instantiate objects in two ways, on the stack as a variable declaration, or on the heap with the new keyword.

What happens when you instantiate an object?

An instance of an object can be declared by giving it a unique name that can be used in a program. This process is known as instantiation. A class can also be instantiated to create an object, a concrete instance of the class. The object is an executable file that can run on a computer.


6 Answers

Object a has automatic storage duration so it will be deleted automatically at the end of the scope in which it is defined. It doesn't make sense to attempt to delete it manually. Manually deletion is only required for objects with dynamic storage duration such as *pa which has been allocated using new.

like image 55
CB Bailey Avatar answered Oct 04 '22 21:10

CB Bailey


  1. The objects live time is limited to the scope the variable is defined in, once you leave the scope the object will be cleaned up. In c++ a scope is defined by any Block between { an the corresponding }.
  2. Here only the pointer is on the stack and not the object, so when you leave the scope only the pointer will be cleaned up, the object will still be around somewhere.

To the part of deleting an object, delete not only calls the destructor of your object but also releases its memory, this would not work as the memory management of the stack is automated by the compiler, in contrast the heap is not automated and requires calls to new and delete to manage the live time of an object.
Any object created by a call to new has to be deleted once, forgetting to do this results in an memory leak as the objects memory will never be released.

like image 35
josefx Avatar answered Oct 04 '22 21:10

josefx


Approach 1 declared a variable and created an object. In Approach 2, you created an instance and pointer to it.

EDIT : In approach 1, the object will go out of scope and will be automatically deleted. In approach 2, the pointer will be automatically deleted, but not what it is pointing to. That will be your job.

like image 31
fastcodejava Avatar answered Oct 04 '22 21:10

fastcodejava


Imagine stack as void* stack = malloc(1.000.000);
Now, this memory block is managed internally by the compiler and the CPU.
It is a shared piece of memory. Every function can use it to store temporary objects there.

That's called automatic storage. You cannot delete parts of that memory because its purpose is
to be used again again. If you explicitly delete memory, that memory returns back to the system,
and you don't want that to happen in a shared memory.

In a way, automatic objects are also get deleted. When an object gets out of scope the compiler places
an invisible call to object's destructor and the memory is available again.

like image 23
Nick Dandoulakis Avatar answered Oct 04 '22 20:10

Nick Dandoulakis


You cannot delete objects on the stack because it's implemented in memory exactly that way -- as a stack. As you create objects on the stack, they are added on top of each other. As the objects leave scope, they are destroyed from the top, in the opposite order they were created in (add to the top of the stack, and remove from the top of the stack). Trying to call delete on something in the stack would break that order. The analogy would be like trying to pull some paper out of the middle of a stack of papers.

The compiler controls how objects are created and removed on the stack. It can do this because it knows exactly how large each object on the stack is. Since the stack size is set at compile time, it means that allocating memory for things on the stack is extremely fast, much faster than allocating memory from the heap, which is controlled by the operating system.

like image 27
JonM Avatar answered Oct 04 '22 20:10

JonM


Allocation does two things:
1) Allocates memory for the object
2) Calls the constructor on the allocated memory

Deletion does two things:
1) Calls the destructor on the object
2) Deallocates the memory used by the destructed object

When you allocate on the stack (A a;), you're telling the compiler "please make an object for me, by allocating memory, then call the constructor on that memory. And while you're at it, could you handle calling the destructor and freeing the memory, when it goes out of scope? Thanks!". Once the function (main) ends, the object goes out of scope, the destructor is called, and the memory is freed.

When you allocate on the heap (A* pa = new A();), you're telling the compiler "please make an object for me. I know what I'm doing, so don't bother calling the destructor or freeing the memory. I'll tell you when to do it, some other time". Once the function (main) ends, the object you allocated stays in scope, and is not destructed or freed. Hopefully you have a pointer to it stored somewhere else in your program (as in, you copied pa to some other variable with a bigger scope). You're gonna have to tell the compiler to destruct the object and free the memory at some point in the future. Otherwise, you get a memory leak.

Simply put, the "delete" command is only for objects allocated on the heap, because that's the manual memory management interface in C++ - new/delete. It is a command for the heap allocator, and the heap allocator doesn't know anything about stack allocated objects. If you try to call delete on a stack allocated object, you might as well have called it on a random memory address - they're the same thing as far as the heap allocator is concerned. Very much like trying to access an object outside array bounds:

int a[10];
std::cout << a[37] << "\n"; // a[37] points at... ? no one knows!

It just isn't meant to do that :)

Edit: P.S. Memory leaks are more important when you are allocating memory in a function other than main. When the program ends, leaked memory gets deallocated, so a memory leak in main might not be a big deal, depending on your scenario. However, destructors never get called on leaked objects. If the destructor does something important, like closing a database or a file, then you might have a more serious bug on your hands.

like image 36
Merlyn Morgan-Graham Avatar answered Oct 04 '22 20:10

Merlyn Morgan-Graham