1

I have some classes kind of like this:

struct Foo {
    char *data;
    Foo(args) { /* initialize data */ }
    ~Foo() { /* clean up data */ }
};

struct Bar {
    ...
    Foo getFoo() const { /* properly initialize and return a Foo */ }
};

And I want to do this:

memcpy(dst, barInstance.getFoo().data, size);

My question is the memcpy well-defined, or will the temporary Foo's destructor leave me with a dangling pointer before the invocation of memcpy? (assume dst, and size are correct.)

I know there is a very simple workaround by writing

{
    Foo tmp = barInstance.getFoo();
    memcpy(dst, tmp.data, size);
} // tmp destructed here after memcpy()

but I am curious if it is necessary.

Nicu Stiurca
  • 8,747
  • 8
  • 40
  • 48
  • 1
    Your `data` pointer isn't going anywhere until the end of the scope. – 500 - Internal Server Error Jan 16 '15 at 02:42
  • the bar.getFoo(); seems to return a shallow copy of a destructed object. make sure you have defined a copy constructor for 'Foo' – Maher Jan 16 '15 at 02:50
  • @Maher I should have mentioned that there is some refcounting going on inside both `Foo` and `Bar`, so shallow copy is OK _so long as the_ `Foo` _object remains in scope_. So my question is still if the `Foo` destructor is guaranteed to not be invoked until _after_ the call to `memcpy` completes. – Nicu Stiurca Jan 16 '15 at 03:12
  • @500 Yes, but where exactly is the end of scope for the `Foo` temporary returned by `Bar::getFoo()` in the argument list to `memcpy`? Before or after the call to `memcpy`? I know in the workaround I included, the scope of `tmp` is clearly at the closing brace after the `memcpy`; but in the first case, where the temporary is anonymous, I'm not so sure. – Nicu Stiurca Jan 16 '15 at 03:13
  • @SchighSchagh Its lifetime ends at the end of the full expression (the semicolon `;`) after the full expression is evaulated. – David G Jan 16 '15 at 03:26

0 Answers0