Thread: When does this object instance get cleaned up?

  1. #1
    Registered User
    Join Date
    Oct 2017
    Posts
    23

    When does this object instance get cleaned up?

    The situation I'm asking about is in the comments. Basically, when does "s" of type Stupid get cleared?

    Code:
    class Stupid
    {
        int size;
        int *array;
    public:
            Stupid(){}
            Stupid(int arraysize)
                    {
                            size = arraysize;
                            array = new int[size];
                    }
            ~Stupid()
                    {
                            delete array;
                    }
    };
    
    
    class Container
    {
    private:
            Stupid s; // declared here. I assume this calls the default constructor?
            int size;
    public:
            Container(int stupidsize)
                    {
                            size = stupidsize;
                            s = Stupid(size); // instantiaed here. What happens to the original s?
                    }
    };
    Last edited by joshuastuden; 08-15-2018 at 10:58 PM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Perhaps put a meaningful cout statement in each constructor and try it?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Oct 2017
    Posts
    23
    Quote Originally Posted by Salem View Post
    Perhaps put a meaningful cout statement in each constructor and try it?
    Hmm. It seems like that it's destroyed when the Container object is destroyed. Effectively, it stays in memory despite not being used.

  4. #4
    Registered User
    Join Date
    Oct 2017
    Posts
    23
    It seems like to avoid this thing from taking up memory, I need to do Stupid *s and then use s = new Stupid(size);

    Am I correct?

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Well as written, your assignment creates a memory leak.
    Code:
    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    class Stupid
    {
        int size;
        int *array;
    public:
            Stupid(){
                cout << "default ctor Stupid at " << reinterpret_cast<void*>(this) << endl;
            }
            Stupid(int arraysize)
                    {
                            cout << "Overload ctor Stupid at " << reinterpret_cast<void*>(this) << endl;
                            size = arraysize;
                            array = new int[size];
                    }
            ~Stupid()
                    {
                            cout << "default dtor Stupid at " << reinterpret_cast<void*>(this) << endl;
                            delete array;
                    }
    };
    
    
    class Container
    {
    private:
            Stupid s;
            int size;
    public:
            Container(int stupidsize)
                    {
                            cout << "Overload ctor Container at " << reinterpret_cast<void*>(this) << endl;
                            size = stupidsize;
                            s = Stupid(size);
                    }
    };
    
    int main ( ) {
        Container c(3);
    }
    
    $ g++ foo.cpp
    $ ./a.out 
    default ctor Stupid at 0x7ffc5bd53bf0
    Overload ctor Container at 0x7ffc5bd53bf0
    Overload ctor Stupid at 0x7ffc5bd53bb0
    default dtor Stupid at 0x7ffc5bd53bb0
    default dtor Stupid at 0x7ffc5bd53bf0
    *** Error in `./a.out': double free or corruption (fasttop): 0x00000000011cc030 ***
    s gets default constructed at the point your container is constructed, but the assignment completely trashes it.

    If you have non-trivial ctor and dtor, you probably need the copy assignment ctor as well.
    Rule of three (C++ programming) - Wikipedia


    > I need to do Stupid *s and then use s = new Stupid(size);
    Well it's one way I suppose.
    It might be a good way if size is large and perhaps in some way optional or needed later. Then you don't immediately waste a lot of resources creating something you might not need.

    Another way is to just use an initialisation list.
    Code:
    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    class Stupid
    {
        int size;
        int *array;
    public:
            Stupid(){
                cout << "default ctor Stupid at " << reinterpret_cast<void*>(this) << endl;
                size = 0;
                array = 0;
            }
            Stupid(int arraysize)
                    {
                            cout << "Overload ctor Stupid at " << reinterpret_cast<void*>(this) << endl;
                            size = arraysize;
                            array = new int[size];
                    }
            ~Stupid()
                    {
                            cout << "default dtor Stupid at " << reinterpret_cast<void*>(this) << endl;
                            delete array;
                    }
    };
    
    
    class Container
    {
    private:
            Stupid s;
            int size;
    public:
            Container(int stupidsize) : s(stupidsize)
                    {
                            cout << "Overload ctor Container at " << reinterpret_cast<void*>(this) << endl;
                            size = stupidsize;
                            //s = Stupid(size); // s is now constructed in the initialisation list
                    }
    };
    
    int main ( ) {
        Container c(3);
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Jun 2017
    Posts
    157
    What's the point of this code?
    By using a std::vector there would be no need to worry about copy/move semantics and memory leaks.

  7. #7
    Registered User
    Join Date
    Oct 2017
    Posts
    23
    Thanks for this. How does the initialization list help, though? It seems that "Stupid s" would still get created, then thrown away when the initialization list gets created... I supposed I can try it with the couts to see if this is correct.

    Edit: you are correct. Interesting. I have to read more about these initialization lists.

    Quote Originally Posted by Salem View Post
    Well as written, your assignment creates a memory leak.
    Code:
    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    class Stupid
    {
        int size;
        int *array;
    public:
            Stupid(){
                cout << "default ctor Stupid at " << reinterpret_cast<void*>(this) << endl;
            }
            Stupid(int arraysize)
                    {
                            cout << "Overload ctor Stupid at " << reinterpret_cast<void*>(this) << endl;
                            size = arraysize;
                            array = new int[size];
                    }
            ~Stupid()
                    {
                            cout << "default dtor Stupid at " << reinterpret_cast<void*>(this) << endl;
                            delete array;
                    }
    };
    
    
    class Container
    {
    private:
            Stupid s;
            int size;
    public:
            Container(int stupidsize)
                    {
                            cout << "Overload ctor Container at " << reinterpret_cast<void*>(this) << endl;
                            size = stupidsize;
                            s = Stupid(size);
                    }
    };
    
    int main ( ) {
        Container c(3);
    }
    
    $ g++ foo.cpp
    $ ./a.out 
    default ctor Stupid at 0x7ffc5bd53bf0
    Overload ctor Container at 0x7ffc5bd53bf0
    Overload ctor Stupid at 0x7ffc5bd53bb0
    default dtor Stupid at 0x7ffc5bd53bb0
    default dtor Stupid at 0x7ffc5bd53bf0
    *** Error in `./a.out': double free or corruption (fasttop): 0x00000000011cc030 ***
    s gets default constructed at the point your container is constructed, but the assignment completely trashes it.

    If you have non-trivial ctor and dtor, you probably need the copy assignment ctor as well.
    Rule of three (C++ programming) - Wikipedia


    > I need to do Stupid *s and then use s = new Stupid(size);
    Well it's one way I suppose.
    It might be a good way if size is large and perhaps in some way optional or needed later. Then you don't immediately waste a lot of resources creating something you might not need.

    Another way is to just use an initialisation list.
    Code:
    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    class Stupid
    {
        int size;
        int *array;
    public:
            Stupid(){
                cout << "default ctor Stupid at " << reinterpret_cast<void*>(this) << endl;
                size = 0;
                array = 0;
            }
            Stupid(int arraysize)
                    {
                            cout << "Overload ctor Stupid at " << reinterpret_cast<void*>(this) << endl;
                            size = arraysize;
                            array = new int[size];
                    }
            ~Stupid()
                    {
                            cout << "default dtor Stupid at " << reinterpret_cast<void*>(this) << endl;
                            delete array;
                    }
    };
    
    
    class Container
    {
    private:
            Stupid s;
            int size;
    public:
            Container(int stupidsize) : s(stupidsize)
                    {
                            cout << "Overload ctor Container at " << reinterpret_cast<void*>(this) << endl;
                            size = stupidsize;
                            //s = Stupid(size); // s is now constructed in the initialisation list
                    }
    };
    
    int main ( ) {
        Container c(3);
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 0
    Last Post: 06-13-2011, 10:46 AM
  2. Replies: 4
    Last Post: 11-14-2006, 11:52 AM
  3. Object reference not set to instance of an object
    By patricio2626 in forum C++ Programming
    Replies: 6
    Last Post: 10-26-2006, 08:12 AM
  4. ERRPR: Object reference not set to an instance of an object
    By blackhack in forum C++ Programming
    Replies: 1
    Last Post: 07-13-2005, 05:27 PM
  5. Remote Method return object instance?
    By BigDaddyDrew in forum C# Programming
    Replies: 0
    Last Post: 07-20-2004, 11:19 AM

Tags for this Thread