Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Destructor called when returning value

Tags:

c++

I've got a class and I'm trying to return it's instance, but the destructor is called before I can return it, which and when it really does fall out of scope in a later functions it's destructor is called again and causes a break. I edited it to fix the error, but I was wondering if it's supposed to be calling it's destructor.

CBuffer BufferReader::read(const int size){
    const auto raw = read_raw(); 
    skip(size);
    return CBuffer(raw, size, true);

    // Dstructor is called in this example

    CBuffer out(read_raw(), size, true);
    skip(size);
    return std::move(out);
}
like image 255
Joshua Waring Avatar asked Mar 18 '23 23:03

Joshua Waring


1 Answers

You are returning a copy of the CBuffer. The original CBuffer that was created inside the function is destroyed when the function exits -- at least logically. Typically a compiler will elide the copy as an optimization unless that optimization is disabled (by making a debug build, for example).

Using std::move doesn't really change this. The copy that is created can just be done more efficiently by stealing the guts out of the original CBuffer. The original CBuffer still has to be destroyed, it just may not contain any real data. A move constructor always needs to leave the original object in a valid state, so it can be safely destroyed.

For example:

struct CBuffer {
    char* data;

    CBuffer(CBuffer&& original)
       : data(original.data)
    {
        original.data = nullptr;
    }

    ~CBuffer() { delete [] data; }  // data may be null, but that is fine
                                    // delete will not do anything in that case.
};

If you can use std::vector instead, that is even better, since it handles these details for you.

like image 132
Vaughn Cato Avatar answered Mar 23 '23 16:03

Vaughn Cato