Reputation: 15010
I have a memory struct as shown below.
struct memoryStruct {
uint8_t* memory;
size_t size;
};
My code requires me to call free(memory)
at multiple places in my code. To avoid this scenario I am thinking of wrapping it in a unique_ptr
.
I have the following
struct memoryStruct {
uint8_t* memory;
size_t size;
};
struct memoryStructDeleter {
void operator()(memoryStruct* p) const
{
free(p);
}
};
How do I initialize m_chunk shown below. I want to allocate a memory of size using malloc
to memory field and update size accordingly.
std::unique_ptr<memoryStruct> m_chunk;
Upvotes: 0
Views: 979
Reputation: 5095
Assuming you cannot change the struct at all (you should, if you can) and you only want to call malloc
and free
and not new
and delete
(which are superior), you can do the following:
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;
}
}
Upvotes: 1
Reputation: 597111
You would need something like this:
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));
}
Which can be greatly simplified if you get rid of malloc()
altogether and use new
/new[]
or std::make_unique()
instead:
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);
Which can then be simplified even further if you use std::vector
instead of 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);
Upvotes: 1