qse/doc/page/mem.doc

87 lines
3.1 KiB
Plaintext

/** @page mem Memory Management
@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.
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
@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;
// Create a private heap using the default memory manager
heap = qse_xma_open (QSE_NULL, 0, 1024 * 1024); // 1M heap
// Initialize a memory manager with the heap
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;
// You can pass 'mmgr' when you create/initialize a different object.
....
....
// Destroy the private heap
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
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
*ptr = 20; // access the block
qse_fma_free (fma, ptr); // free the block
qse_fma_close (fma); // destroy the allocator
@endcode
@section mem_pma Simple Memory Pool Allocator
If you want to allocate blocks quickly but don't want to resize or
deallocate the blocks individually, you can use #qse_pma_t.
@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
*/