C структура с указателем для включения в unique_ptr - PullRequest
0 голосов
/ 20 февраля 2020

У меня есть структура памяти, как показано ниже.

struct memoryStruct {
    uint8_t* memory;
    size_t size;
};

Мой код требует от меня вызова free(memory) в нескольких местах моего кода. Чтобы избежать этого сценария, я думаю обернуть его в unique_ptr.

. У меня есть следующее

struct memoryStruct {
    uint8_t* memory;
    size_t size;
};

struct memoryStructDeleter {
    void operator()(memoryStruct* p) const
    {
        free(p);
    }
};

Как мне инициализировать m_chunk, показанный ниже. Я хочу выделить память размером using malloc для поля памяти и соответственно обновить размер.

std::unique_ptr<memoryStruct> m_chunk;

Ответы [ 2 ]

1 голос
/ 20 февраля 2020

Вам понадобится что-то вроде этого:

struct memoryStruct {
    uint8_t* memory;
    size_t size;
};

struct memoryStructDeleter {
    void operator()(memoryStruct* p) const
    {
        if (p) {
            free(p->memory);
            free(p);
        }
    }
};

...

std::unique_ptr<memoryStruct, memoryStructDeleter> m_chunk( static_cast<memoryStruct*>(std::malloc(sizeof(memoryStruct))) );
if (m_chunk) {
    m_chunk->size = DesiredSize;
    m_chunk->memory = static_cast<uint8_t*>(std::malloc(m_chunk->size));
}

Что может быть значительно упрощено, если вы полностью избавитесь от malloc() и будете использовать new / new[] или std::make_unique() вместо:

struct memoryStruct {
    std::unique_ptr<uint8_t[]> memory;
    size_t size;

    memoryStruct(size_t asize = 0) : memory(new uint8_t[asize]), size(asize) {}
    // or:
    // memoryStruct(size_t asize = 0) : memory(std::make_unique<uint8_t[]>(asize)), size(asize) {}
};

...

std::unique_ptr<memoryStruct> m_chunk(new memoryStruct(DesiredSize));
// or:
// std::unique_ptr<memoryStruct> m_chunk = std::make_unique<memoryStruct>(DesiredSize);

Что может быть еще более упрощено, если вы используете std::vector вместо std::unique_ptr:

struct memoryStruct {
    std::vector<uint8_t> memory;
    memoryStruct(size_t size = 0) : memory(size) {}
};

...

std::unique_ptr<memoryStruct> m_chunk(new memoryStruct(DesiredSize));
// or:
// std::unique_ptr<memoryStruct> m_chunk = std::make_unique<memoryStruct>(DesiredSize);
1 голос
/ 20 февраля 2020

Предполагая, что вы не можете изменить структуру вообще (вы должны, если можете), и вы хотите звонить только malloc и free, а не new и delete (которые выше), вы можете сделать следующее:

struct memoryStructDeleter {
    void operator()(memoryStruct* p) const
    {
        if (p) {
            if (p->memory) {
                 free(p->memory);
            }
            free(p);
        }
    }
};

std::unique_ptr<memoryStruct, memoryStructDeleter> create(size_t s) {
    std::unique_ptr<memoryStruct, memoryStructDeleter> ret(static_cast<memoryStruct*>(malloc(sizeof(memoryStruct))));
    if (!ret) {
        return nullptr;
    }
    ret->memory = static_cast<uint8_t*>(malloc(s * sizeof(uint8_t)));
    if (ret->memory) {
        return ret;
    } else {
        return nullptr;
    }
}
...