Reassign unique_ptr object with make_unique statements - Memory leak?

前端 未结 3 2139
深忆病人
深忆病人 2021-02-12 17:50

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

auto buff = std::make_unique(128);
buff = std::make_unique(512)         


        
相关标签:
3条回答
  • 2021-02-12 17:57

    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.

    0 讨论(0)
  • 2021-02-12 18:08

    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.

    0 讨论(0)
  • 2021-02-12 18:10

    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
    
    0 讨论(0)
提交回复
热议问题