你可以将shared_ptr用于C风格数组的RAII吗?

bsr*_*uth 26 c++ raii shared-ptr

我正在研究一段代码,它有许多可能的故障点,导致它提前退出函数.我正在与之交互的库要求将C样式的数组传递给函数.所以,我没有在每个出口点调用数组上的delete,而是这样做:

void SomeFunction(int arrayLength)
{
   shared_ptr<char> raiiArray(new char[arrayLength]);
   pArray = raiiArray.get();

   if(SomeFunctionThatRequiresCArray(pArray) == FAILED) { return; }

   //etc.
}
Run Code Online (Sandbox Code Playgroud)

我想使用unique_ptr,但我当前的编译器不支持它,并且引用计数开销在这种情况下并不重要.

我只是想知道在与遗留代码接口时是否有人对这种做法有任何想法.

更新 我完全忘了shared_ptr呼叫delete而不是delete [].我刚看到没有内存泄漏,并决定采用它.甚至没想过用矢量.因为我最近一直在钻研新的(对我来说)C++我认为我有一个案例"如果你拥有的唯一工具是锤子,那么一切看起来都像钉子一样." 综合征.感谢您的反馈.

UPDATE2我想我会改变这个问题并提供一个答案,让那些犯了同样错误的人更有价值.虽然有类似的替代方案scoped_array,shared_array并且vector,您可以使用a shared_ptr来管理数组的范围(但在此之后我不知道为什么我会想要):

template <typename T>
    class ArrayDeleter
    {
    public:
        void operator () (T* d) const
        {
            delete [] d;
        }
    };

void SomeFunction(int arrayLength)
    {
       shared_ptr<char> raiiArray(new char[arrayLength], ArrayDeleter<char>());
       pArray = raiiArray.get();

       if(SomeFunctionThatRequiresCArray(pArray) == FAILED) { return; }

       //etc.
    }
Run Code Online (Sandbox Code Playgroud)

Jon*_*cto 27

不要使用shared_ptrscoped_ptr保存指向动态分配的数组的指针.shared_ptr和scoped_ptr用于delete ptr;在指针不再被引用/超出范围时进行清理,这会在动态分配的数组上调用未定义的行为.相反,使用delete[] ptr;在破坏时正确使用的shared_array或scoped_array .

要回答你的问题,如果你不打算通过智能指针,请使用scoped_array,因为它的开销要小于shared_array.

或者,std::vector用作数组存储(向量已保证连续的内存分配).

  • 默认情况下,shared_ptr和scoped_ptr使用delete ptr,但您可以提供自己的删除函数或函子. (9认同)

Nem*_*vic 15

如果您正在处理数组boost::scoped_array,请使用,甚至更好std::vector.


Jus*_*ini 7

我强烈建议只使用一个std::vector.元素在vectors堆上分配,并且当vector超出范围时,无论何处退出函数,都将删除元素.

为了传递一个vector需要C风格数组的遗留代码,只需传递即可&vectorName[0].元素保证在内存中是连续的.


小智 6

C++ 11用户的一些评论:

因为shared_ptr,在C++ 11中有一个默认删除器,用于定义<memory>和标准兼容的数组类型(最终草案),因此可以在没有其他花式删除器的情况下使用它们:

std::shared_ptr<char> raiiArray(new char[arrayLength], std::default_delete<char[]>()); 
Run Code Online (Sandbox Code Playgroud)

unique_ptr在C++ 11中有一个部分专业化来处理new[]delete[].但不幸的是,它没有共享行为.必须是一个很好的理由没有这样的专业,shared_ptr但我没有找,如果你知道,请分享.


Nik*_*sov 5

boost::scoped_ptr这个.

  • 在这种情况下scoped_array (7认同)