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

  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
    I created another member in the class that returns a List, in there, the copying works.

    Here's how I test it:
    I add a deconstructor into the List class that prints "Destroying"
    then I write the following command:
    (a_list.cut(Someiterator)).view();

    now, after the cut function returns the value, I see "Destroying" and then all the elements of the partly destroyed list are printed on the screen(the last element has been deteriorated).

    But when I write:
    (a_list.returner()).view();

    Code:
    List List::returner()
    {
        List a;
        return a;
    }
    I see the elements printed on the screen and after the printing finishes, I see "Destroying", which is logical, as the command ends and the variables in the previous scope(List::returner()'s scope) are destroyed.

  13. #13
    Registered User
    Join Date
    Jan 2005
    Location
    Estonia
    Posts
    131
    Yes, the push_xxx functions use the dynamic memory allocation - "new".

  14. #14
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    No... I meant your list was cut. You are returning a shortened version of your list. If you are getting problems with it by having seemingly random results at the end of the list, then it's probably because your Elem members are not being correctly updated.

    It was a guess. I can't see the problem with the code provided.
    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.

  15. #15
    Registered User
    Join Date
    Jan 2005
    Location
    Estonia
    Posts
    131
    Quote Originally Posted by Mario F.
    No... I meant your list was cut. You are returning a shortened version of your list. If you are getting problems with it by having seemingly random results at the end of the list, then it's probably because your Elem members are not being correctly updated.

    It was a guess. I can't see the problem with the code provided.
    How can it be then, that the View() functions correctly display all the elements BEFORE the return statement, but AFTER the returning is done, the elements are no longer displayed correctly.

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