Reassign unique_ptr object with make_unique statements - Memory leak?

和自甴很熟 提交于 2020-07-04 22:01:49

问题


I don't get what following statement would do (specially second line)?

auto buff = std::make_unique<int[]>(128);
buff = std::make_unique<int[]>(512);

Will the second call to make_unique followed by assignment operator will de-allocate memory allocated by first call, or will there be memory leak? Must I have to use buff.reset(new int[512]); ?

I've debugged it, but didn't find any operator= being called, nor any destructor be invoked (by unique_ptr).


回答1:


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());
}

yields assembly:

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



回答2:


Move assignment operator is called, which does

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

No leak here, as it does reset, which will deallocate.




回答3:


There is no memory leak here, the assignment will deallocate the resources associated with the first allocation. Not seeing it in the debugger most likely means the relevant call was just optimised out. Try compiling with -O0 if you want to see it.



来源:https://stackoverflow.com/questions/37806616/reassign-unique-ptr-object-with-make-unique-statements-memory-leak

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!