CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8

Thread: Accepting a value by reference upon return

  1. #1
    Join Date
    Dec 2010
    Posts
    907

    Accepting a value by reference upon return

    Code:
    A& a = b.GetValue();
    
    
    A& B::GetValue(std::set<A, scomparator>& nodes, int i) {
       std::set<A, scomparator>::iterator it = nodes.begin();
       std::advance(it, i);
       A& n = (A&)*it;		 
       return n;
    }
    By the time an instance of A is returned from B, it gets destroyed and everything inside A becomes
    0xfeeefeee?
    Why, if I use A instead of A&, it is okay, but I don't want to make a copy of it?
    From the debugger, n is a valid node.
    Any ideas?
    Thanks
    Jack
    Last edited by lucky6969b; August 6th, 2015 at 12:34 AM.

  2. #2
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: Accepting a value by reference upon return

    If you need random access, use a vector, not a set.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  3. #3
    Join Date
    Dec 2010
    Posts
    907

    Re: Accepting a value by reference upon return

    I need to keep the nodes sorted.
    Are there any Sorted Arrays in C++, I wonder?
    Thanks
    Jack

  4. #4
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,768

    Re: Accepting a value by reference upon return

    Quote Originally Posted by lucky6969b
    Are there any Sorted Arrays in C++, I wonder?
    Obviously, you can keep an array (or vector) sorted. The problem (and this is a general algorithm and data structure problem, not one limited to C++) is that an insertion into the middle of an array/vector takes linear time to move the elements after the insertion point, even though you can use binary search to find the insertion point, so ideally you would construct an unsorted array/vector and sort it once, with minimal insertions into the middle afterwards.

    If you find that your insertions tend to dominate over accessing by index, then your idea of using a std::set might be better.

    Quote Originally Posted by lucky6969b
    By the time an instance of A is returned from B, it gets destroyed and everything inside A becomes
    0xfeeefeee?
    Why, if I use A instead of A&, it is okay, but I don't want to make a copy of it?
    From the debugger, n is a valid node.
    Any ideas?
    If you really do want to by this route, then I suggest that you make your code const-correct: the elements of a set cannot be changed, so you should use a const reference instead:
    Code:
    const A& B::GetValue(const std::set<A, scomparator>& nodes, int i) {
       std::set<A, scomparator>::const_iterator it = nodes.begin();
       std::advance(it, i);
       return *it;
    }
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  5. #5
    Join Date
    Dec 2010
    Posts
    907

    Re: Accepting a value by reference upon return

    Hello laserlight,
    Thanks for helping.
    I don't know why when the element A is returned, it still got destroyed immediately.
    The pointers inside there are 0xfeeefeee and some garbage values for other member variables?
    Thanks
    Jack

  6. #6
    Join Date
    Dec 2010
    Posts
    907

    Re: Accepting a value by reference upon return

    Sorry, Fixed that. I got an indirect method to call, so messing things up...

  7. #7
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Accepting a value by reference upon return

    [QUOTE=lucky6969b;2184855]
    Code:
       A& n = (A&)*it;
    I don't know why this cast is needed here, but for me, it is a *massive* red flag.

    As for the initial question, if B gets destroyed and holds the reference to A, then of course, your A& a is going to hold a reference to garbage.

    You need to either:
    - Guarantee your B outlives your A&.
    - Create a copy of your A& for safekeeping.

    BTW:
    Code:
    A& a = b.GetValue();
    A& B::GetValue(std::set<A, scomparator>& nodes, int i) {
    The function call and function signature doesn't match...?

    Note that with "const correct" argument in-then-out-functions, there are subtle ways to shoot yourself in the foot with the compiler being none the wiser:
    [const]A& a = B::GetValue(std::set<A>{A(), A()} , 1)
    [/const]

    Here, you are declaring an anonymous temporary set. You are passing it to GetValue, which is legal, because it accepts a const ref. The function then returns by reference the internal A by reference (still legal). You then bind the returned reference to your own local reference A&. Still legal. But then your temporary is destroyed, and you have a dangling reference.

    It's not that rare, and the compiler does not see it at all. You usually see this under this form:
    Code:
    const int& m = max(3, 4); // Oops
    So always be careful about binding return values to const references. The original reference will often die sooner than you expect...
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  8. #8
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Accepting a value by reference upon return

    if you don't need indexed access, then an std::map will give you the appearance of a 'sorted array' (without the []-type indexed access)
    you can iterate over the map in weak ordering according to the key value.

    laserlight's post about sorting a vector only once is a good approach for some cases, but isn't for others.

    if you are slowly building a vector but meanwhile doing lots of lookups, then a binary search lookup + occasional inserts (with binary search to look up where) could be orders of magnitude faster than linear lookups, adding to the end, and sorting once.

    but depending, but the reverse can equally true, there is a definate overhead to keeping the array sorted by inserting compared to tail insertion an sorting once.

    know how your program behaves, and pick the best approach for your circumstances.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)