0

What is the difference between these two instantiation and method call types?

Take this code for example:

class Test
{
public:
    Test(int nrInstance)
    {
        std::cout << "Class " << nrInstance << " instanced " << std::endl;

    }

    ~Test() { }

    int retornaValue()
    {
        return value;

    }

private:
    const int value = 10;

};


int main(int argc, char *argv[])
{
    Test *test1 = new Test(1);
    Test  test2(2);

    std::cout << test1->retornaValue() << std::endl;
    std::cout << test2.retornaValue()  << std::endl;

    return 0;
}

From what ive read, using the first way, the variable is allocated in the heap, and the second, in the stack, but arent both inside the Main scope, and being deallocated after the function exits?

Also, calling methods is different in both examples, why?

Leandragem
  • 100
  • 1
  • 12
  • Thanks for the edit @remyabel, this way is better, it avoids confusion. – Leandragem Nov 05 '14 at 00:02
  • You seem to have very little understanding of c++. You should probably do some research or read a book before asking super basic questions like this. This is c++ 101 – Falmarri Nov 05 '14 at 00:02
  • Well youre right. I am new to C++, but i`m trying to understand these topics better before I move on to the next step. Would you recommend a nice reading material for C++? – Leandragem Nov 05 '14 at 00:04
  • @Leandragem, http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – chris Nov 05 '14 at 00:11

7 Answers7

1

but arent both inside the Main scope, and being deallocated after the function exits?

No not at all... *test1 will not be deallocated until you call delete on it.

Falmarri
  • 47,727
  • 41
  • 151
  • 191
1

Your right that both variables are in the Main scope and deallocated after the function exits, but in the first case it is the Test* value that is deallocated, not the Test instance itself. Once the pointer is deallocated, the class instance is leaked. In the second case, the Test instance is on the stack, so the instance itself is deallocated.

Also, calling methods is different in both examples, why?

Unless overloaded, foo->bar is equivalent to (*foo).bar. The calling syntax is different because in the first case, test1 is a pointer to an instance, and in the second, test2 is an instance.

MooseBoys
  • 6,641
  • 1
  • 19
  • 43
1

but arent both inside the Main scope, and being deallocated after the function exits?

The stack instance is unwound as the scope is closed, and thus deallocated. The pointer is as well, but the object it points to is not. You must explicitly delete instances allocated with new.

Niels Keurentjes
  • 41,402
  • 9
  • 98
  • 136
1

In the first example, you are creating both a pointer to the object on the stack, and the object itself on the heap.

In the second example you are creating the object itself on the stack.

The syntax difference is the difference between calling a function through a pointer and calling it on an object directly.

You are wrong about the first example being cleaned up, you need a delete before the pointer goes out of scope or you have what is known as a memory leak. Memory leaks will be cleaned up by the OS when the program exits, but good practice is to avoid them.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • Thanks for the reply. Is there any `best pratices` regarding this? Like when to use one, or another? – Leandragem Nov 05 '14 at 00:06
  • 2
    @Leandragem use a local (stack) object unless you need the lifetime of the object to exist beyond the current block, or if you're passing ownership of the object to something else. Or sometimes if you need a large object or array that won't fit on the stack, e.g. millions of elements. – Mark Ransom Nov 05 '14 at 00:08
1

You've clearly stated the difference in your question, one is on the stack, and one is on the heap. And yes, when main() exits, it will be deallocated. Now let's take a different approach.

#include <iostream>
using namespace std;

class MemoryLeak{
    private:
        int m_instance
    public:
        MemoryLeak(int i) : m_instance(i) 
            { cout << "MemoryLeak " << i << " created.\n"; }
        ~MemoryLeak() { cout << "MemoryLeak " << m_instance << " deleted.\n"; }
};

void makeMemoryLeak(){
    static int instance = 0
    MemoryLeak mem1(++instance);
    MemoryLeak* mem2 = new MemoryLeak(++instance);
}

int main(){
    for(int x = 0; x < 10; ++x){
        makeMemoryLeak();
        cout << endl;
    }

    cin.get(); // Wait to close

    return 0;
}

You will see 20 "New MemoryLeak created." lines but only 10 "MemoryLeak deleted" lines. So those other 10 instances are still in memory until you close the program. Now let's say that that program never shuts down, and MemoryLeak has a size of 20 bytes. and makeMemoryLeak() runs once a minute. After one day, or 1440 minutes, you'll have 28.125 kb of memory that is taken up, but you have no way to access.

The solution would be to change makeMemoryLeak()

void makeMemoryLeak(){
    MemoryLeak mem1;
    MemoryLeak* mem2 = new MemoryLeak();
    delete mem2;
}
David
  • 4,744
  • 5
  • 33
  • 64
1

Regarding what gets created and destroyed:

struct Test {};

void func()
{
    // instantiate ONE automatic object (on the stack) [test1]
    Test test1;

    // Instantiate ONE automatic object (on the stack) [test2]
    // AND instantiate ONE object from the free store (heap) [unnamed]
    Test* test2 = new Test; // two objects!!

} // BOTH automatic variables are destroyed (test1 & test2) but the 
  // unnamed object created with new (that test2 was pointing at)
  // is NOT destroyed (memory leak)
Galik
  • 47,303
  • 4
  • 80
  • 117
  • Because you're exiting main, *test2 **is** destroyed. As soon as your exit your program, the OS cleans up any allocated memory. If you do something similar to my answer, that shows how it's not deleted. – David Nov 05 '14 at 00:31
0

if you dont delete Test1 (Test*) before coming out of main, it will cause memory leak.

vinod sahu
  • 67
  • 12