shared_ptr 是否在堆上分配了空闲内存?

Does shared_ptr free memory allocated on the heap?

所以在我的工作中我无法访问完整的 std 库,因为......只是因为(公司废话原因)。我不能使用 unique_ptr 但我可以访问 shared_ptr 并且我正在使用 c++11。所以...

我正在使用一个预先存在的(内部)库函数,该函数为我获取数据并通过原始点 returns 它(比方说 uint8_t*)。我想将此数据作为 shared_ptr.

存储在我的 class 中

根据Will a shared_ptr automatically free up memory?

http://herbsutter.com/2013/05/29/gotw-89-solution-smart-pointers/

看来,如果我在堆上分配内存并将其存储在 shared_ptr 中,智能指针应该为我释放内存(uint8_t* 数据)。这是真的?任何与文献的链接都会有所帮助。另外,从这些链接看来我不能使用 make_shared 因为我是 "adopting a raw pointer from somewhere else."

class myClass
{
public:
    shared_ptr<uint8_t> iv_data;
    // rest of class
};

其他功能范围

data_size = getDataSize(...);  // legacy internal function
uint8_t* data = new uint8_t[data_size];
getData(data, data_size); // legacy internal function

myClass object;
object.iv_spd_data = std::shared_ptr<uint8_t>(l_spd_data);

// if scope ends here will I get a memory leak for not freeing data

我想那行: object.iv_spd_data = std::shared_ptr<uint8_t>(l_spd_data); 应该: object.iv_data = std::shared_ptr<uint8_t>(l_spd_data);?

shared_ptr 可以与其他 shared_ptr 对象共享指针的所有权。当拥有您的指针的 shared_ptr 中的最后一个被销毁时,指针指向的对象将被删除。

对于 object.iv_data = std::shared_ptr<uint8_t>(l_spd_data);,您正在创建临时 shared_ptr 并将其分配给 object.iv_data。实际上,您在 object.iv_data 和临时 shared_ptr 之间共享 l_spd_data 的所有权。由于临时 shared_ptr 在该语句之后立即被销毁,因此现在唯一的所有者是 object.iv_datamyClass object被销毁时,iv_data被销毁,l_spd_data被删除。

所以在这种情况下你不会发生内存泄漏。

这里是一个使用 shared_ptr<> 数组类型和自定义删除器的例子。我添加了一些打印语句来显示程序的流程。注意删除时不需要知道分配的大小,只需要类型是数组即可。不使用 delete[] 删除分配的数组是未定义的行为;这就是为什么需要自定义删除器的原因。

ideone

上查看实际效果
#include <iostream>
#include <memory>
#include <cstdint>

using namespace std;

template< typename T >
struct array_deleter
{
  void operator ()( T const * p)
  { 
    cout << "using delete[]" << endl;
    delete[] p; 
  }
};

int8_t* allocate_func()
{
  cout << "allocating array" << endl;
  return new int8_t[10];
}

int main() {
    int8_t *ptr = allocate_func();
    cout << "creating smart pointer" << endl;
    shared_ptr<int8_t> sptr(ptr, array_deleter<int8_t>());
    cout << "exiting main" << endl;
    return 0;
}