使用make_unique语句重新分配unique_ptr对象 - 内存泄漏?

Aja*_*jay 10 c++ memory-leaks unique-ptr c++11 c++14

我没有得到以下声明会做什么(特别是第二行)?

auto buff = std::make_unique<int[]>(128);
buff = std::make_unique<int[]>(512);
Run Code Online (Sandbox Code Playgroud)

第二次调用make_unique后跟赋值运算符将取消分配第一次调用分配的内存,还是会出现内存泄漏?我必须要用buff.reset(new int[512]);吗?

我调试了它,但没有找到任何operator=被调用,也没有调用任何析构函数(by unique_ptr).

V. *_*nko 8

调用移动赋值运算符,这样做

if (this != &_Right)
{   // different, do the swap
    reset(_Right.release());
    this->get_deleter() = _STD move(_Right.get_deleter());
}
Run Code Online (Sandbox Code Playgroud)

这里没有泄漏,因为它会重置,这将解除分配.


Sme*_*eey 5

这里没有内存泄漏,该分配将取消分配与第一个分配关联的资源。在调试器中看不到它很可能意味着相关调用已被优化。-O0如果要查看,请尝试使用进行编译。


Ric*_*ges 4

gcc 5.3:

#include <memory>

extern void emit(int*);

int main()
{
    // declare and initialise buf
    auto buff = std::make_unique<int[]>(128);

    // make_unique on the RHS returns a temporary
    // - therefore an r-value reference

    // therefore this becomes and operator=(unique_ptr&&)
    // (move-assignment)
    buff = std::make_unique<int[]>(512);

    // something to get the compiler to emit code
    emit(buff.get());
}
Run Code Online (Sandbox Code Playgroud)

产量装配:

main:
        pushq   %r12
        movl    $512, %edi
        pushq   %rbp
        pushq   %rbx
        call    operator new[](unsigned long)  ; <-- new (1)
        movl    $64, %ecx
        movq    %rax, %rbp
        xorl    %eax, %eax
        movq    %rbp, %rdi
        rep stosq
        movl    $2048, %edi
        call    operator new[](unsigned long) ; <<-- new (2)
        movl    $2048, %edx
        xorl    %esi, %esi
        movq    %rax, %rdi
        movq    %rax, %rbx
        call    memset
        movq    %rbp, %rdi
        call    operator delete[](void*)       ;<-- delete (1)
        movq    %rbx, %rdi
        call    emit(int*)
        movq    %rbx, %rdi
        call    operator delete[](void*)       ;<-- delete (2)
        popq    %rbx
        xorl    %eax, %eax
        popq    %rbp
        popq    %r12
        ret
        movq    %rax, %r12
        movq    %rbp, %rbx
.L3:
        movq    %rbx, %rdi
        vzeroupper
        call    operator delete[](void*)       ;<-- handles a failed assignment
        movq    %r12, %rdi
        call    _Unwind_Resume
        movq    %rax, %r12
        jmp     .L3
Run Code Online (Sandbox Code Playgroud)

  • 在我看来,解释智能指针如何工作以及为什么没有泄漏比一堆特定于编译器的程序集输出更有用. (20认同)
  • @gigabytes 请原谅我。我在 1981 年学会了汇编程序。这是我的第一种计算机语言,所以我倾向于用它来看待其他所有语言。我认为带注释的程序集是最好的解释。我还有什么不清楚的吗? (2认同)