1

I've got a little bug that is blowing my mind. Perhaps it is simple, but I'm totally lost.

I have a basic POD struct:

    struct Data{
    bool isInvalid=false;
    vec3 *vector; //vec3 is another struct with x,y,z components
    Node*node;
    bool isFresh;
    unsigned int *form;
    };

I have a function:

  Data getData(){
    Data forReturn;
    //...populates the forReturn struct
    cout<<forReturn.vector->x; //logs correctly a value 
    return forReturn;
   }

The cout log correctly shows that my return Data has been populated. But when I call this function from another function, a different story presents:

  Data newData=getData(); //logs as above
  cout<<newData.vector->x; //is empty!!

What is going on here?! My log output shows these two lines side by side since they occurring right after the other, but what is going on? This is not multithreaded, so variables and pointers should not be changing between these two lines!

johnbakers
  • 24,158
  • 24
  • 130
  • 258
  • Can you show the whole definition of `Data`? – Andy Prowl May 19 '13 at 09:48
  • what does `forReturn.vector` point to? BTW `forReturn` is not a pointer so `forReturn->vector` would not compile. – juanchopanza May 19 '13 at 09:49
  • Is `Data` perhaps a typedef for `struct Data *`, or something like that? If so, you really should show that, it fundamentally changes the question. –  May 19 '13 at 09:50
  • @juanchopanza my apologies I had the `.` and `->` switched in the above code, typo. not that way in my actual code. – johnbakers May 19 '13 at 09:53
  • 1
    Show the code that populates `forReturn->vector`. Ideally, show a minimal program that compiles and reproduces the issue. – Andrei May 19 '13 at 09:54
  • @AndyProwl I have updated the question with the entire POD – johnbakers May 19 '13 at 09:57
  • 1
    @Fellowshee: Now you should show how you populate it – Andy Prowl May 19 '13 at 09:59
  • @AndyProwl you solved it in your comment to an answer. I had foolishly populated using a local object in the function, thus the object goes out of scope after the return. Thanks. – johnbakers May 19 '13 at 10:11

2 Answers2

4

If written that way, the local Data (forReturn) is copied during the return-process. So its vital that your copy-constructur of the Data-class is implemented the right way (copies all members the right way)

pbhd
  • 4,384
  • 1
  • 20
  • 26
  • 1
    It is also vital the `...//populates the forReturn struct` does not associate the `vector` pointer to a local `vec3` object... – Andy Prowl May 19 '13 at 09:51
2

I can't tell for sure unless I see the real code you have, but my bet is that your program has undefined behavior, because you are dereferencing a dangling pointer. I believe that in your getData() function you are letting forReturn.vector point to a local object with automatic storage duration, which is destroyed when returning from getData(), like so:

Data getData(){
    Data forReturn;
    vec3 myVector;
    // ...
    forReturn.vector = &myVector;
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    // ...
    cout<<forReturn.vector->x; // logs correctly a value 
    return forReturn;
}

In the example above I am returning the Data object forReturn by value, meaning the implicitly declared move constructor (in C++11) or copy constructor (in C++03) will be invoked.

Since these implicitly-generated special member functions perform a memberwise move or copy of the data structure's members, the vector pointer is copied, meaning that what I am returning is an object of type Data whose vector pointer points to an object that has gone out of scope already.

This is a time bomb. As soon as that pointer gets dereferenced, "Boom". Notice, that the "Boom" can actually be a very silent explosion - Undefined Behavior means that anything could happen, including nothing.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
  • As Scott Meyers likes to mention, _undefined behavior_ can also mean that your hard drive could be erased. :) – johnbakers May 19 '13 at 11:27
  • @Fellowshee: [Right](http://stackoverflow.com/questions/16428234/why-does-this-not-produce-a-segmentation-fault/16428253#16428253) ;) – Andy Prowl May 19 '13 at 11:32