Thread: CConstructor Infinite Recursion!

  1. #76
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629

    Is it efficient?

    This might sound ridiculous but is using a copy constructor to deep copy objects into a list efficient, really?

    I mean, it seems kind of fast if the list can only contain references, since they can't
    would it not be faster if they contain the pointers to the object in memory?
    So i am talking about dynamic allocation here.

    I tried that, to make a list of points to object in memory and was shocked to discover that while it deletes the pointer, it doesn't however call the destructor of that object!!

    i wrote a function to delete it manually.

    But if it STL list doesn't call the destructor on erase of a pointer to object using the free store, is it a good idea then.
    Which is more efficient?
    You ended that sentence with a preposition...Bastard!

  2. #77
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    Quote Originally Posted by whiteflags View Post
    Now, remember, the STL requires copyable objects. So what does this mean? Well, you were already told that this:
    Code:
    void push_back ( const T &x )
    {
        T newNode( x );
    }
    would be virtually the same as copying it here:
    Code:
    void push_back ( T x )
    If it is the same then it is pointless to me!
    i mean
    just do
    void push_back(T x)
    and get it over with. :S
    You ended that sentence with a preposition...Bastard!

  3. #78
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by Eman View Post
    Yeah i know, except the declaration is:

    push_back(const T&)

    it only copies the reference of the object. Since it isn't copying the object itself
    there is no reason for the invocation copy constructor.
    The copying takes place *inside* of the function itself, if at all (the object could simply be ignored, for all we know). Anyway, the parameter's signature effectively tells you what is going to happen:
    A) const T&: the address is copied. It's assumed (but not guaranteed) that the object at that address will not be modified. Within the function, it is then typically passed to the copy constructor or assignment operator of other objects, and the like.
    B) T&: the address is copied. It's assumed that the object at that address may be modified at some point in the future.
    C) T: the compiler generates code to allocate room on the stack for an object, invoke it's copy constructor, and then pass a T& as the actual function parameter.* The rules of (B) then apply.

    Note that the above becomes more complicated where templates are involved. Consider:

    Code:
    template < typename T >
    void foo( T data ) // pass by value, right?
    {    }
    
    int main( void )
    {
        int data;
        foo( data ); // pass by value - same as foo< int >( data );
        foo< int const& >( data ); // pass by const reference! 
    }
    *This aspect is actually implementation defined; The object could be copied on the stack, stored directly in registers, or even accesses via some global pointer. The important point is that the effect is the same, at least as far as the user (ie: developer) is concerned.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  4. #79
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733
    Quote Originally Posted by Eman View Post
    I tried that, to make a list of points to object in memory and was shocked to discover that while it deletes the pointer, it doesn't however call the destructor of that object!!

    i wrote a function to delete it manually.

    But if it STL list doesn't call the destructor on erase of a pointer to object using the free store, is it a good idea then.
    Read about smart pointers. They are implemented as classes which wrap raw pointers, allocating and freeing memory automatically. Raw pointer is a primitive variable holding address; there is absolutely no automation for it.

    Quote Originally Posted by Eman View Post
    Which is more efficient?
    It depends on the amount of memory, which the object occupies and performance of copy operation.

  5. #80
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Quote Originally Posted by Eman View Post
    This might sound ridiculous but is using a copy constructor to deep copy objects into a list efficient, really?

    I mean, it seems kind of fast if the list can only contain references, since they can't
    would it not be faster if they contain the pointers to the object in memory?
    So i am talking about dynamic allocation here.
    OK hold up. These are worries that are unfounded.

    If you instantiate something like

    list<myclass> mylist;

    Then by default, the STL will use an allocator that is written and provided by the compiler writer working with ::operator new and ::operator delete (the free store). If you do something like this:

    list<myclass*> myplist;

    the allocator is still used, but you've added an extra layer of indirection. The allocator is only responsible for the myclass pointer and not the ultimate myclass object. So you get this headache as a result:

    Quote Originally Posted by Eman View Post
    I tried that, to make a list of points to object in memory and was shocked to discover that while it deletes the pointer, it doesn't however call the destructor of that object!!

    i wrote a function to delete it manually.
    Having the STL containers carry raw pointers can make the STL useless, as you are now responsible for some memory management again. If you're concentrating on getting the easiest solution for yourself coded, then you are doing it wrong.

    I doubt the object is entirely ignored as Substantiani says in his post, since the object is copied into a list node according to the manual page. To address the efficiency question, more importantly, a copy would seem necessary. If the list creates a copy of your object on the free store with the allocator, it can manage the object without worrying what exactly you passed it.

    If the STL were stupid, this:

    Code:
     mylist.push_back( Dog( stuff ) );
    would mean that a temporary object that is destroyed after the push_back call is a part of the list. So rather than be worried about efficiency that you can't or won't measure... it does at least work. If your concerns were actual concerns the STL would be even worse than it is.

  6. #81
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    Quote Originally Posted by whiteflags View Post
    OK hold up. These are worries that are unfounded.

    If you instantiate something like

    list<myclass> mylist;

    Then by default, the STL will use an allocator that is written and provided by the compiler writer working with :perator new and :perator delete (the free store). If you do something like this:

    list<myclass*> myplist;

    the allocator is still used, but you've added an extra layer of indirection. The allocator is only responsible for the myclass pointer and not the ultimate myclass object. So you get this headache as a result:



    Having the STL containers carry raw pointers can make the STL useless, as you are now responsible for some memory management again. If you're concentrating on getting the easiest solution for yourself coded, then you are doing it wrong.

    I doubt the object is entirely ignored as Substantiani says in his post, since the object is copied into a list node according to the manual page. To address the efficiency question, more importantly, a copy would seem necessary. If the list creates a copy of your object on the free store with the allocator, it can manage the object without worrying what exactly you passed it.

    If the STL were stupid, this:

    Code:
     mylist.push_back( Dog( stuff ) );
    would mean that a temporary object that is destroyed after the push_back call is a part of the list. So rather than be worried about efficiency that you can't or won't measure... it does at least work. If your concerns were actual concerns the STL would be even worse than it is.
    grand!
    I will stick to the way I did it before then, Thanks!
    You ended that sentence with a preposition...Bastard!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Template Recursion Pickle
    By SevenThunders in forum C++ Programming
    Replies: 20
    Last Post: 02-05-2009, 09:45 PM
  2. convert Recursion to linear can it be done
    By umen242 in forum C++ Programming
    Replies: 2
    Last Post: 10-15-2008, 02:58 AM
  3. Recursion... why?
    By swgh in forum C++ Programming
    Replies: 4
    Last Post: 06-09-2008, 09:37 AM
  4. Recursion
    By Lionmane in forum C Programming
    Replies: 11
    Last Post: 06-04-2005, 12:00 AM
  5. a simple recursion question
    By tetra in forum C++ Programming
    Replies: 6
    Last Post: 10-27-2002, 10:56 AM