Пользовательский удалитель std :: unique_ptr перемещается к другому объекту - PullRequest
0 голосов
/ 07 апреля 2020

Я пытаюсь использовать пользовательское средство удаления с std::unique_ptr, а затем возвращаю std::unique_ptr объекту класса через std::move. Этот объект будет удален в конце программы.

Это мое определение пользовательского средства удаления и функции, где он используется:

using deleter_wrap_t = std::unique_ptr<Structure1, std::function<void(Structure1*)>>;

static  deleter_wrap_t create_buffer(int32_t size)
{
    printf("Launch>> deleter_wrap_t\n");
    auto buf = deleter_wrap_t(new Structure1(), &CustDeleteFunc);
    if (!buf)
        return nullptr;

    buf->Data = new int32_t[size];
    if (!buf->Data)
        return nullptr;

    buf->dataSize = size;
    return std::move(buf);
}

И это пользовательская функция средства удаления:

void CustDeleteFunc(Structure1* pbs)
{
    printf("Launch>> CustDeleteFunc\n");
    if(pbs)
    {
        delete [] pbs->Data;
        pbs->dataSize = 0;
    }
}

И после запуска программы на выходе у меня есть:

Launch>> deleter_wrap_t

И никаких следов запуска CustDeleteFunc

Кто-нибудь знает, почему CustDeleteFunc нет не запускается и как заставить его работать?


UPD:

Это минимальный воспроизводимый пример, и он прекрасно работает:

#include <iostream>
#include <functional>
#include <memory>

typedef struct {
    unsigned char* Data;
    int32_t dataSize;
} Structure1;

using deleter_wrap_t = std::unique_ptr<Structure1, std::function<void(Structure1*)>>;

void CustDeleteFunc(Structure1* pbs)
{
    printf("Launch>> CustDeleteFunc\n");
    if (pbs)
    {
        delete[] pbs->Data;
        pbs->dataSize = 0;
    }
}

static  deleter_wrap_t create_buffer(int32_t size)
{
    printf("Launch>> deleter_wrap_t\n");
    auto buf = deleter_wrap_t(new Structure1(), &CustDeleteFunc);
    if (!buf)
        return nullptr;

    buf->Data = new unsigned char[size];
    if (!buf->Data)
        return nullptr;

    buf->dataSize = size;
    return std::move(buf);
}


class myClass{
public:
    myClass(){
        printf("constructor\n");
    };
    void init(){
        m_dst = create_buffer(3);
        auto tmp = m_dst.get();
        tmp->dataSize = 0;
    };

    virtual ~myClass() noexcept
    {
        close();
    };

protected:
    deleter_wrap_t m_dst;
    void close() noexcept{
        //m_dst.reset(); //commented or not - it works clear
    }
};


int main() {
    myClass m;
    m.init();
    return 0;
}

Итак, я в смятении, потому что min пример работает хорошо, и в моем большом проекте он не работает, поэтому я получаю утечку памяти.

В проекте m_ww может указывать какой-то другой объекты (как tmp в примере выше), но эти tmp s не влияют на средство удаления.

Итак, есть ли у вас какие-либо ответы / предположения, которые могут вызвать такое поведение, что CustDeleteFunc не звонит?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...