2011-08-14 10:04:14 +00:00
|
|
|
/** @page mem Memory Management
|
|
|
|
|
2011-08-15 03:07:31 +00:00
|
|
|
@section mem_overview Overview
|
|
|
|
|
|
|
|
A memory manager is an instance of a structure type #qse_mmgr_t. Creating
|
|
|
|
and/or initializing an object requires a memory manager to be passed in.
|
|
|
|
|
|
|
|
The default memory manager is merely a wrapper to memory allocation functions
|
|
|
|
provided by underlying operating systems: HeapAlloc/HeapReAlloc/HeapFree
|
|
|
|
on _WIN32 and malloc/realloc/free on other platforms. You can get this default
|
|
|
|
memory manager with qse_getdflmmgr() and can change it with qse_setdflmmgr().
|
|
|
|
|
|
|
|
Typically, the name of a function creating an object begins with @b qse_,
|
|
|
|
ends with @b _open, and accepts a memory manager as the first parameter.
|
|
|
|
See qse_mbs_open() for instance. So you can customize memory management
|
|
|
|
at the per-object level.
|
|
|
|
|
2011-10-03 01:25:23 +00:00
|
|
|
Three types of special memory allocators are provided in the library.
|
|
|
|
- #qse_xma_t - generaic private heap allocator
|
|
|
|
- #qse_fma_t - fixed-size block allocator
|
|
|
|
- #qse_pma_t - pool-based block allocator
|
|
|
|
|
2011-08-15 03:07:31 +00:00
|
|
|
@section mem_xma Priviate Heap
|
|
|
|
|
|
|
|
While the default memory manager allocates memory from a system-wide heap,
|
|
|
|
you can create a private heap and use it when you create an object.
|
|
|
|
The #qse_xma_t type defines a private heap manager and its functions offer
|
|
|
|
sufficient interface to form a memory manager over a private heap.
|
|
|
|
|
|
|
|
A typical usage is shown below:
|
|
|
|
|
|
|
|
@code
|
|
|
|
qse_mmgr_t mmgr;
|
|
|
|
|
2011-10-03 01:25:23 +00:00
|
|
|
// Create a private heap using the default memory manager
|
|
|
|
heap = qse_xma_open (QSE_NULL, 0, 1024 * 1024); // 1M heap
|
2011-08-15 03:07:31 +00:00
|
|
|
|
2011-10-03 01:25:23 +00:00
|
|
|
// Initialize a memory manager with the heap
|
2011-08-15 03:07:31 +00:00
|
|
|
mmgr.alloc = (qse_mmgr_alloc_t)qse_xma_alloc;
|
|
|
|
mmgr.realloc = (qse_mmgr_realloc_t)qse_xma_realloc;
|
|
|
|
mmgr.free = (qse_mmgr_free_t)qse_xma_realloc;
|
|
|
|
mmgr.ctx = heap;
|
|
|
|
|
2011-10-03 01:25:23 +00:00
|
|
|
// You can pass 'mmgr' when you create/initialize a different object.
|
2011-08-15 03:07:31 +00:00
|
|
|
....
|
|
|
|
....
|
|
|
|
|
2011-10-03 01:25:23 +00:00
|
|
|
// Destroy the private heap
|
2011-08-15 03:07:31 +00:00
|
|
|
qse_xma_close (heap);
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
Note that creating a private heap requires a memory manager, too. The example
|
|
|
|
above used the default memory manager to create a private heap within the
|
|
|
|
global heap. This means that you can split a heap to smaller subheaps.
|
|
|
|
|
|
|
|
@section mem_fma Fixed-size Block Allocator
|
|
|
|
|
2011-10-03 01:25:23 +00:00
|
|
|
If memory blocks to allocate share the same size, you can use #qse_fma_t
|
|
|
|
for performance. It achieves fast memory allocation as it knows the block
|
|
|
|
size in advance. The blocks allocated with this memory allocator
|
|
|
|
don't outlive the memory allocator itself. That is, qse_fma_close() or
|
|
|
|
qse_fma_fini() invalidates all the pointers allocated with qse_fma_alloc().
|
|
|
|
|
|
|
|
@code
|
|
|
|
qse_fma_t* fma; int* ptr;
|
|
|
|
fma = qse_fma_open (QSE_NULL, 0, sizeof(int), 10, 0); // create an allocator
|
|
|
|
ptr = (int*)qse_fma_alloc (fma, sizeof(int)); // allocate a block
|
2012-07-20 11:08:48 +00:00
|
|
|
*ptr = 20; // access the block
|
|
|
|
qse_fma_free (fma, ptr); // free the block
|
2011-10-03 01:25:23 +00:00
|
|
|
qse_fma_close (fma); // destroy the allocator
|
|
|
|
@endcode
|
2011-08-15 03:07:31 +00:00
|
|
|
|
2011-08-22 23:26:26 +00:00
|
|
|
@section mem_pma Simple Memory Pool Allocator
|
|
|
|
|
2011-10-03 01:25:23 +00:00
|
|
|
If you want to allocate blocks quickly but don't want to resize or
|
2011-08-22 23:26:26 +00:00
|
|
|
deallocate the blocks individually, you can use #qse_pma_t.
|
|
|
|
|
2012-07-20 11:08:48 +00:00
|
|
|
@code
|
|
|
|
qse_pma_t* pma; int* ptr;
|
|
|
|
pma = qse_pma_open (QSE_NULL, 0); // create an allocator
|
|
|
|
ptr = (int*)qse_pma_alloc (pma, sizeof(int)); // allocate a block
|
|
|
|
*ptr = 20; // access the block
|
|
|
|
qse_pma_close (pma); // destroy the allocator
|
|
|
|
@endcode
|
|
|
|
|
2011-08-14 10:04:14 +00:00
|
|
|
*/
|