Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to move unique_ptr to raw pointer?

I have a function that is used to allocate a buffer with given size. The buffer will be preprocess/filled some data before return. This preprocess may return false to represent this buffer is not processed right. So I want to apply RAII on this buffer to avoid early return without delete[] it.

Usually I use unique_ptr to help me to auto release the local allocated object. In this case I need to return this allocated object (Owned by unique_ptr) and transfer the ownership to caller. But the compiler complains that I cannot convert unique_ptr<T[]> to T* while I std::move the unique_ptr. It looks like unique_ptr can only be moved to another unique_ptr instead of raw pointer.

Is any way to transfer the ownership from unique_ptr to a raw pointer? Or just the unique_ptr is not suitable for this case?

bool PreProcess(int* v) { /* return nothing wrong? true: false; */ }

bool GetBuffer(int** ppRetBuf, int size)
{
    std::unique_ptr<int[]> buf(new (std::nothrow) int[size]());
    if(PreProcess(buf.get())
    {
        *ppRetBuf = std::move(buf); // Compiler complains:  
                                    // Error C2440 '=': cannot convert from 'std::unique_ptr<int [],std::default_delete<_Ty>>' to 'int *'
        return true;
    }
    return false; // No need to manually delete[] failure buffer
}

int main()
{
    int * buf = nullptr;
    GetBuffer(&buf, 100);
}
like image 512
Chen OT Avatar asked Oct 22 '15 06:10

Chen OT


2 Answers

How to move unique_ptr to raw pointer?

Well, that's one way of avoiding any benefits of using unique_ptr here.

You can use std::unique_ptr::release() but then the use of unique_ptr is pointless in the first place. Consider returning a unique_ptr instead. That way the caller knows that they own the pointer and the array will be freed when they stop using it. Otherwise you'd have to document that the caller must deallocate and how they must do it.

If that's not an option, then there's no use for unique_ptr at all unless you are doing something that might throw between constructing the array and returning it and left it out for simplicity.

like image 112
eerorika Avatar answered Nov 01 '22 14:11

eerorika


Since ppRetBuf and buf are two different data types the compiler gives the error message for that.

In order to do what you want to do you need to call release on buf

*ppRetBuf = buf.release();
like image 43
AndersK Avatar answered Nov 01 '22 15:11

AndersK