Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. ATL / WTL / STL
  4. STL List - object creation / destruction wierdness

STL List - object creation / destruction wierdness

Scheduled Pinned Locked Moved ATL / WTL / STL
c++question
9 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    neilsolent
    wrote on last edited by
    #1

    Yo coders, I am experimenting with the following code, using VC++ 6: ............. #include "stdafx.h" #include #include #include #include #include using namespace std; class test { public: int m_i; test(int i = 0) { m_i = i; cout << "test object with m_i=" << m_i << " being constructed" << endl; }; ~test() { cout << "test object with m_i=" << m_i << " being deleted" << endl; }; }; typedef list TESTLIST; int main(int argc, char* argv[]) { TESTLIST myTestList; myTestList.push_front(1); myTestList.push_front(2); return 0; } ......... The output of the program is: test object with m_i=1 being constructed test object with m_i=1 being deleted test object with m_i=2 being constructed test object with m_i=2 being deleted test object with m_i=2 being deleted test object with m_i=1 being deleted ........ How is it possible that objects can be constructed once but deleted twice? thanks, Neil

    cheers, Neil

    S Z 2 Replies Last reply
    0
    • N neilsolent

      Yo coders, I am experimenting with the following code, using VC++ 6: ............. #include "stdafx.h" #include #include #include #include #include using namespace std; class test { public: int m_i; test(int i = 0) { m_i = i; cout << "test object with m_i=" << m_i << " being constructed" << endl; }; ~test() { cout << "test object with m_i=" << m_i << " being deleted" << endl; }; }; typedef list TESTLIST; int main(int argc, char* argv[]) { TESTLIST myTestList; myTestList.push_front(1); myTestList.push_front(2); return 0; } ......... The output of the program is: test object with m_i=1 being constructed test object with m_i=1 being deleted test object with m_i=2 being constructed test object with m_i=2 being deleted test object with m_i=2 being deleted test object with m_i=1 being deleted ........ How is it possible that objects can be constructed once but deleted twice? thanks, Neil

      cheers, Neil

      S Offline
      S Offline
      Stuart Dootson
      wrote on last edited by
      #2

      If you add monitoring of the copy constructor, you'll find the missing constructions... #include <iostream> #include <list> using namespace std; class test { public: int m_i; test(int i = 0) { m_i = i; cout << "test object with m_i=" << m_i << " being constructed" << endl; }; test(test const& t) : m_i(t.m_i) { cout << "test object with m_i=" << m_i << " being copy constructed" << endl; }; test& operator=(test const& t) { m_i = t.m_i;return *this; cout << "test object with m_i=" << m_i << " being copy constructed" << endl; }; ~test() { cout << "test object with m_i=" << m_i << " being deleted" << endl; }; }; typedef list<test> TESTLIST; int main(int argc, char* argv[]) { TESTLIST myTestList; myTestList.push_front(1); myTestList.push_front(2); return 0; } gives

      test object with m_i=1 being constructed
      test object with m_i=1 being copy constructed
      test object with m_i=1 being deleted
      test object with m_i=2 being constructed
      test object with m_i=2 being copy constructed
      test object with m_i=2 being deleted
      test object with m_i=2 being deleted
      test object with m_i=1 being deleted

      1 Reply Last reply
      0
      • N neilsolent

        Yo coders, I am experimenting with the following code, using VC++ 6: ............. #include "stdafx.h" #include #include #include #include #include using namespace std; class test { public: int m_i; test(int i = 0) { m_i = i; cout << "test object with m_i=" << m_i << " being constructed" << endl; }; ~test() { cout << "test object with m_i=" << m_i << " being deleted" << endl; }; }; typedef list TESTLIST; int main(int argc, char* argv[]) { TESTLIST myTestList; myTestList.push_front(1); myTestList.push_front(2); return 0; } ......... The output of the program is: test object with m_i=1 being constructed test object with m_i=1 being deleted test object with m_i=2 being constructed test object with m_i=2 being deleted test object with m_i=2 being deleted test object with m_i=1 being deleted ........ How is it possible that objects can be constructed once but deleted twice? thanks, Neil

        cheers, Neil

        Z Offline
        Z Offline
        Zac Howland
        wrote on last edited by
        #3

        When writing classes that you want to place into STL containers, make sure you declare a copy constructor and copy-assignment operator. The containers to a lot of copying, and make use of those two functions. Since you didn't declare one, the compiler generates a default one for you (which basically does a memcpy).

        If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

        N S 2 Replies Last reply
        0
        • Z Zac Howland

          When writing classes that you want to place into STL containers, make sure you declare a copy constructor and copy-assignment operator. The containers to a lot of copying, and make use of those two functions. Since you didn't declare one, the compiler generates a default one for you (which basically does a memcpy).

          If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

          N Offline
          N Offline
          neilsolent
          wrote on last edited by
          #4

          Thanks, I realised my mistake soon after... this is only my 2nd day working with STL! So it is best to only put simple types, strings or pointers in a list then, and not "large" objects directly .. as there doesn't seem to be a member function to remove an object from a list without deleting it! cheers, Neil

          Z 1 Reply Last reply
          0
          • N neilsolent

            Thanks, I realised my mistake soon after... this is only my 2nd day working with STL! So it is best to only put simple types, strings or pointers in a list then, and not "large" objects directly .. as there doesn't seem to be a member function to remove an object from a list without deleting it! cheers, Neil

            Z Offline
            Z Offline
            Zac Howland
            wrote on last edited by
            #5

            You can place large objects in a list if you like, just realize that it will be expensive to do things like sort it (especially if the list has a substantial number of elements). list::erase will remove an element from the list. If the element was controlled by the list (that is, you created a list like list<MyObjects> myList;), then yes, it will be deleted. If you want a copy of it, you should grab it prior to calling erase. If the list was a list of pointers, erase will just delete the pointer. The object the pointer was pointing to will still be there (so make sure you have a pointer that still points to it somewhere or you will have a memory leak).

            If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

            1 Reply Last reply
            0
            • Z Zac Howland

              When writing classes that you want to place into STL containers, make sure you declare a copy constructor and copy-assignment operator. The containers to a lot of copying, and make use of those two functions. Since you didn't declare one, the compiler generates a default one for you (which basically does a memcpy).

              If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

              S Offline
              S Offline
              Stuart Dootson
              wrote on last edited by
              #6

              Zac Howland wrote:

              basically does a memcpy

              Not quite - the Standard says:

              The implicitly defined copy constructor for class X performs a memberwise copy of its subobjects. The order of copying is the same as the order of initialization of bases and members in a userdefined constructor (see 12.6.2). Each subobject is copied in the manner appropriate to its type:

              • if the subobject is of class type, the copy constructor for the class is used;
              • if the subobject is an array, each element is copied, in the manner appropriate to the element type;
              • if the subobject is of scalar type, the builtin assignment operator is used.

              Virtual base class subobjects shall be copied only once by the implicitlydefined copy constructor (see 12.6.2).

              Personally, I only define copy constructor/assignment operator when I've got a member that's not RAII compliant...and then I think 'Why doesn't that sub-object manage itself' and change it so I can use the implicit copy-constructor and assignment operator!

              Z 1 Reply Last reply
              0
              • S Stuart Dootson

                Zac Howland wrote:

                basically does a memcpy

                Not quite - the Standard says:

                The implicitly defined copy constructor for class X performs a memberwise copy of its subobjects. The order of copying is the same as the order of initialization of bases and members in a userdefined constructor (see 12.6.2). Each subobject is copied in the manner appropriate to its type:

                • if the subobject is of class type, the copy constructor for the class is used;
                • if the subobject is an array, each element is copied, in the manner appropriate to the element type;
                • if the subobject is of scalar type, the builtin assignment operator is used.

                Virtual base class subobjects shall be copied only once by the implicitlydefined copy constructor (see 12.6.2).

                Personally, I only define copy constructor/assignment operator when I've got a member that's not RAII compliant...and then I think 'Why doesn't that sub-object manage itself' and change it so I can use the implicit copy-constructor and assignment operator!

                Z Offline
                Z Offline
                Zac Howland
                wrote on last edited by
                #7

                I said "basically" for a reason. Try fitting what the standard declares into a 1 sentence note about why you should declare (or not declare) a copy-constructor.

                Stuart Dootson wrote:

                Personally, I only define copy constructor/assignment operator when I've got a member that's not RAII compliant...and then I think 'Why doesn't that sub-object manage itself' and change it so I can use the implicit copy-constructor and assignment operator!

                I'm just the opposite. I almost always define them explicitly so that if I have problems, I already have the methods there for me to debug and see what is going on. You can't step through implicit functions.

                If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                S 1 Reply Last reply
                0
                • Z Zac Howland

                  I said "basically" for a reason. Try fitting what the standard declares into a 1 sentence note about why you should declare (or not declare) a copy-constructor.

                  Stuart Dootson wrote:

                  Personally, I only define copy constructor/assignment operator when I've got a member that's not RAII compliant...and then I think 'Why doesn't that sub-object manage itself' and change it so I can use the implicit copy-constructor and assignment operator!

                  I'm just the opposite. I almost always define them explicitly so that if I have problems, I already have the methods there for me to debug and see what is going on. You can't step through implicit functions.

                  If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                  S Offline
                  S Offline
                  Stuart Dootson
                  wrote on last edited by
                  #8

                  Sorry - what I should have said was that I didn't like the comparison of the copy constructor to memcpy - it copies each member individually, it doesn't just copy the raw bytes of the object. Which is why I'm quite happy to rely on implicit copy constructors - because 99% of the time, they're implementing what I'd be implementing anyway. I take your point about having copy constructors to step through @ debug time - it's just not something I find myself doing.

                  Z 1 Reply Last reply
                  0
                  • S Stuart Dootson

                    Sorry - what I should have said was that I didn't like the comparison of the copy constructor to memcpy - it copies each member individually, it doesn't just copy the raw bytes of the object. Which is why I'm quite happy to rely on implicit copy constructors - because 99% of the time, they're implementing what I'd be implementing anyway. I take your point about having copy constructors to step through @ debug time - it's just not something I find myself doing.

                    Z Offline
                    Z Offline
                    Zac Howland
                    wrote on last edited by
                    #9

                    Stuart Dootson wrote:

                    Sorry - what I should have said was that I didn't like the comparison of the copy constructor to memcpy - it copies each member individually, it doesn't just copy the raw bytes of the object. Which is why I'm quite happy to rely on implicit copy constructors - because 99% of the time, they're implementing what I'd be implementing anyway.

                    The main reason I compare it to memcpy is simply to emphasize that if you have a pointer member variable, only the pointer value will be copied (that is, a new object that the pointer is pointing to will not be created). As a side note, they will only implement what you would do if your data members are simple types. If they are complex types that don't have a copy-constructor/assignment operator defined, chances are it isn't going to do what you would expect (e.g. if you have a custom vector-type class that doesn't have a copy-constructor).

                    Stuart Dootson wrote:

                    I take your point about having copy constructors to step through @ debug time - it's just not something I find myself doing.

                    After finding myself trying to debug implicit functions several times, I got in the habit of making sure they were explicit. It only takes one time of spending a week trying to figure out why your code doesn't work (when it should) before you want to make sure you don't run into the problem again.

                    If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups