0

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; 
3
  • 1
    When does memory get allocated? Can you replace uint8_t* with unique_ptr<uint8_t[]> ? Commented Feb 20, 2020 at 6:40
  • 2
    @jtbandes or just std::vector<uint8_t> Commented Feb 20, 2020 at 6:58
  • I can't see a good case for dynamically allocating memoryStruct. Can you expand on your use case so we can see if you can avoid this altogether? Commented Feb 20, 2020 at 6:59

2 Answers 2

1

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); 
Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.