简体   繁体   中英

Shared pointer to array in pool-allocated memory

I am working on writing a fixed-capacity, copy-on-write "string" class which is capable of using Allocators for its memory allocations. Eventually, I want to be able to have these "strings" use a memory pool which returns fixed-sized chunks of memory. If the "capacity" of the string being created is less than the pool chunk size, the extra memory is "wasted." If the capacity is larger, this is an assert failure (ie, you cannot create a string that is larger than the pool chunk size).

To implement the copy-on-write behavior, I am trying to figure out how to use this pool to create shared pointers to arrays within this chunk of memory. I can't just use std::shared_ptr(pool.allocate(...)) because I need both the control block AND memory to be allocated in the SAME chunk of memory allocated by the pool.

Visually, the memory should look like:

----------------------------------------------------
|              Memory Pool Chunk                   |
|--------------------------------------------------|
| Control Block | Array of characters ... | UNUSED |
----------------------------------------------------

From my research, I can see that this is example what std::make_shared does; it allocates both the control block and object in a contiguous chunk of memory. However, it also looks like you can't allocate an arbitrarily-sized array using std::make_shared. You can use it to allocate std::array objects, but you of course need to know the size at compile time, whereas the size of the array I want to allocate is known at run-time.

My next thought was to simply implement my own, stripped down shared pointer. Since I don't need weak pointers or custom deleters, this seems like I should just be able to store an allocator and reference count in some sort of "header" in the memory I get back from the pool. Then, the rest of the memory can be used for the array.

However, I cannot figure out how you are supposed to store an allocate within a header and later use the allocator to, for example, make a deep copy of the data.

Could someone help either:

a) Direct me towards a way of doing this using the already build-in standard library constructs OR

b) Help me figure out how to implement my own shared pointer that meets the requirements above

I would avoid trying to use shared_ptr for this. Not just because you need C++20 in order for allocate_shared to work on arrays, but also because it is inefficient for your embedded needs.

The shared_ptr control block has two reference counts in order to allow for weak pointers. Your particular use case doesn't need weak pointers, so you only need one count. The control block has a pointer to the object it manages. In your use case, the array is always right after the control block. The control block has a copy of the allocator, but your string class already has that, so it doesn't need it in the control block. And so on.

You should use a hand-rolled solution so that you can minimize the amount of book-keeping memory, thus maximizing the amount of actual string storage you get.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM