当重新分配std::unique_ptr时,内存是否被释放?

5

给定以下内容:

{
    std::unique_ptr<char[]> foo;
    foo = std::make_unique<char[]>(100);
    foo = std::make_unique<char[]>(200);
}

当使用第二次调用重新分配foo时,第一次调用make_unique分配的内存是否会被释放?


2
你可以重新“分配”foo,而不会导致内存泄漏。 - Ted Lyngmo
2
附注:一般情况下,优先使用std::vector而不是智能指针数组。性能分析或其他情况会告诉你何时需要切换到std::vector之外的数据结构。 - user4581301
3个回答

12

这段代码没有泄漏。对于std::unique_ptroperator=,当从另一个被赋值的unique_ptr转移所有权时,会调用现有内存的Deleter(在本例中为delete[])。

根据cppreference:

std::unique_ptr<T,Deleter>::operator=

将所有权从r转移到*this,就好像通过调用reset(r.release())然后从std::forward<E>(r.get_deleter())分配get_deleter()一样。

std::unique_ptr<T,Deleter>::reset

针对*this管理的指针current_ptr,按照以下顺序执行以下操作:

  • 保存当前指针的副本old_ptr = current_ptr
  • 用参数覆盖当前指针current_ptr = ptr
  • 如果旧指针不为空,则删除先前管理的对象
    if(old_ptr) get_deleter()(old_ptr)

2
你只需要定义foo一次。
具体来说,在作用域的第一行:
std::unique_ptr<char[]> foo;

默认情况下,将调用默认构造函数进行默认初始化,该构造函数使用 nullptr 进行初始化。

另外两行代码将为 foo 分配一个新值,而不会重新定义变量,否则会出现错误。

如果您为 foo 分配新值,则保证赋值运算符将释放先前拥有的内存。


1

是的,unique_ptr有一个数组专用版本,当unique_ptr超出作用域时会调用数组范围内的析构函数:

https://en.cppreference.com/w/cpp/memory/unique_ptr

正如您在最后一个示例中所看到的那样,它创建了一个D的数组,然后调用了所有已创建的D的析构函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接