Thread: Grabbing the return value before it's erased.

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Jan 2005
    Location
    Estonia
    Posts
    131

    Grabbing the return value before it's erased.

    Hello.

    I made a class:
    Code:
    class Test
    {
        public:
        int a;
    };    //there is no special usage for this class. I just want to show my problem
    
    Test a_function()
    {
        Test temp;
        temp.a = 4;
        return temp;
    }
    
    int main()
    {
       Test b = a_function();
       cout << b.a << endl;
    }
    //the problem is, that the return value of a_function gets destroyed BEFORE the assignment is done, thus the "cout ... " will print unexpected results.

    How can I make a copy of the return value before it's destroyed.

  2. #2
    Registered User
    Join Date
    May 2006
    Posts
    903
    Return a pointer to new'ed memory. I think if you make the variable (temp) static it might work because it never gets deleted until the end. You'd have to try though, I'm not sure at all if this is correct.

  3. #3
    Registered User
    Join Date
    Jan 2005
    Location
    Estonia
    Posts
    131
    but what about the functions that return 'int'-s as their return values. those return values are used to specify the success or failure of the function - like int main(). This should mean, that actually the variable is not destroyed right away, but e.g.: after the expression it occurrs in.

    I am not sure about the behaviour. Does anyone else have an idea?

  4. #4
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    You are returning a copy of a local variable (temp). There is nothing wrong with that.

    Can it be you are trying instead to return a local reference?
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  5. #5
    Registered User
    Join Date
    Jan 2005
    Location
    Estonia
    Posts
    131
    I shortened the code. It looks something like this:

    Code:
    class List
    {
        public:
            List();
            List cut(Iterator&);
    };
    
    List List::cut(Iterator& it)
    {
                List new_list; //List is a class defined by me, not the std::list<>
                pos = pos->next;
                for (;pos != NULL;pos = pos->next)
                {
                    new_list.push_back(pos->value);
                    new_list.view();
                }
                return new_list;
    
    }
    
    int main()
    {
       List li = an_existing_List.cut(SomeIterator);
    }

  6. #6
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    And what is the error you get?
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Location
    Estonia
    Posts
    131
    there are 2 elements in the class List:
    Elem start;
    Elem end;

    they are respectively the start- and endpoint of the list; //their position is constant - they don't move
    They are initialized in the List() constructor.
    There is a member function void List::View() which prints the linked list (all the elementsbetween start and end (inclusive)). Elements are added between the start and end with "new".

    Before the new_list is returned in the List::cut function, the view shows all the elements correctly, but:

    List new_li = an_existing_list.cut(SomeIterator);
    new_li.View(); // prints correctly the first element and all the elements between start and end, but then the last element will contain some random numbers(which didn't appear before the "return" statement in the cut function).

  8. #8
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Because the list is now shortened and start and end remained the same?
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  9. #9
    Registered User
    Join Date
    Jan 2005
    Location
    Estonia
    Posts
    131
    Quote Originally Posted by Mario F.
    Because the list is now shortened and start and end remained the same?
    Ok, here's the whole class and the 'Elem' stuct:

    Code:
    class List
    {
        int ID_j2rg;
        Elem start, end;
        public:
            List();
            void push_front(const int&);
            void push_back(const int&);
            void add_after(const Iterator&, const int value);
            void add_after(const int, const int);
            void view(bool mode = 0);   //kui mode = 0, siis edaspidi, kui 1 siis tagurpidi
            List bond(List&);
            List cut(Iterator&);
            Elem* get_begin() { return &start; }
            Elem* get_end() { return &end; }
    };
    
    struct Elem
    {
        struct Elem* prev, *next;
        int value;
        int ID;
        Elem() { value = 0; ID = -1; prev = next = NULL; }
        Elem(const int& a, const int new_id) { value = a; ID = new_id; prev = next = NULL; }
    };

  10. #10
    Registered User
    Join Date
    Jan 2005
    Location
    Estonia
    Posts
    131
    Quote Originally Posted by Mario F.
    Because the list is now shortened and start and end remained the same?
    I shortened the list for other's to read the important parts like the constructors. List:ush_front doesn't influence the problem imho, so I left it out from the shortened version.

  11. #11
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    I suppose you are allocating memory in your push_xxx functions

    For such classes you have to provide copy constructors

    If you don't - the compiler creates one for you - just using member by member assignments...

    In this case all pointers point to the same memory as the original class instance,
    And after the original class is destroyed - your copy has dangling pointer here and there...

    With your function you invoke copy-constructor in the return statement from the the local variable to the temp-variable being returned...

    After that the operator = is invoked to copy values from the temp variable to the newly created var in the calling function. It means this operator also should be provided
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  12. #12
    Registered User
    Join Date
    Jan 2005
    Location
    Estonia
    Posts
    131
    Quote Originally Posted by vart
    I suppose you are allocating memory in your push_xxx functions

    For such classes you have to provide copy constructors

    If you don't - the compiler creates one for you - just using member by member assignments...

    In this case all pointers point to the same memory as the original class instance,
    And after the original class is destroyed - your copy has dangling pointer here and there...

    With your function you invoke copy-constructor in the return statement from the the local variable to the temp-variable being returned...

    After that the operator = is invoked to copy values from the temp variable to the newly created var in the calling function. It means this operator also should be provided
    I think that's the problem. So I'll have to find another way around it.

  13. #13
    Registered User
    Join Date
    Dec 2006
    Posts
    17
    Quote Originally Posted by hardi
    I think that's the problem. So I'll have to find another way around it.
    Create a copy constructor that handles the heap-based allocations you made with new() or keep it all on the heap and pass a pointer around.

  14. #14
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by hardi
    I think that's the problem. So I'll have to find another way around it.
    Note that for classes using dynamic memory allocation directly you should always provide copyConstructor and operator =
    If you think you don't need them and don't want to implement - a good practice is to create empty functions for them and make them private.

    In this case if you still use one of the above by mistake - compiler will note you
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  15. #15
    Registered User
    Join Date
    Dec 2006
    Posts
    17
    Quote Originally Posted by vart
    I suppose you are allocating memory in your push_xxx functions

    For such classes you have to provide copy constructors

    If you don't - the compiler creates one for you - just using member by member assignments...

    In this case all pointers point to the same memory as the original class instance,
    And after the original class is destroyed - your copy has dangling pointer here and there...
    Spot on, I was just trying to put that into words myself

    You can't declare something on the stack then expect the code to just know that you've extended it onto the heap when you go and pass it by value :P

    Personally I'd declare the list on the heap and pass a pointer. You're just creating overhead by copying everything constantly anyway... I suppose that depends on the purpose behind your program to some extent though.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Code review
    By Elysia in forum C++ Programming
    Replies: 71
    Last Post: 05-13-2008, 09:42 PM
  2. Pong is completed!!!
    By Shamino in forum Game Programming
    Replies: 11
    Last Post: 05-26-2005, 10:50 AM
  3. sort linked list using BST
    By Micko in forum C Programming
    Replies: 8
    Last Post: 10-04-2004, 02:04 PM
  4. opengl help
    By heat511 in forum Game Programming
    Replies: 4
    Last Post: 04-05-2004, 01:08 AM
  5. opengl code not working
    By Unregistered in forum Windows Programming
    Replies: 4
    Last Post: 02-14-2002, 10:01 PM