C结构,其指针将被包装在unique_ptr中

C struct with a pointer to be wrapped in a unique_ptr

本文关键字:unique ptr 包装 结构 指针      更新时间:2023-10-16

我有一个内存结构,如下所示。

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;

您需要这样的东西:

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

假设您根本无法更改结构(如果可以的话,您应该更改(,并且您只想调用mallocfree,而不想调用newdelete(它们更高级(,则可以执行以下操作:

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