MEMORY(3) Library Functions Manual MEMORY(3)

MemorySmart memory management.

#include <Memory.h>

void *
MemoryAllocate(size_t, const char *, int);

void *
MemoryReallocate(void *, size_t, const char *, int);

void
MemoryFree(void *, const char *, int);

size_t
MemoryAllocated(void);

void
MemoryFreeAll(void);

MemoryInfo *
MemoryInfoGet(void *);

size_t
MemoryInfoGetSize(MemoryInfo *);

const char *
MemoryInfoGetFile(MemoryInfo *);

int
MemoryInfoGetLine(MemoryInfo *);

void *
MemoryInfoGetPointer(MemoryInfo *);

void
MemoryIterate(void (*) (MemoryInfo *, void *), void *);

void
MemoryHook(void (*) (MemoryAction, MemoryInfo *, void *, void *);

void
MemoryHexDump(MemoryInfo *, void (*) (size_t, char *, char *, void *), void *);

Memory is an API that allows for smart memory management and profiling. It wraps the standard library functions malloc(3), realloc(3), and free(3), and offers identical semantics, while providing functionality that the standard library doesn't have, such as getting statistics on the total memory allocated on the heap, and getting the size of a block of memory given a pointer. Additionally, thanks to preprocessor macros, the exact file and line number at which an allocation, reallocation, or free occured can be obtained given a pointer. Finally, all the blocks allocated on the heap can be iterated and evaluated, and a callback function can be executed every time a memory operation occurs.

A number of macros are available, which make using the Memory API much more useful. () expands to () with the __FILE__ and __LINE__ constants for the second and third arguments respectively. Likewise, () and () expand to () and MemoryFree() with __FILE__ and __LINE__ as the second and third parameters. This allows the API to be used exactly how the standard library would be used. In fact, the functions which these macros expand to are not intended to be called directly; only use the macros for the best results.

If all memory used in the program is managed by this API, there are some helpful functions that allow the program to probe the state of the heap. These functions are described here.

() gets the total memory that the program has on the heap. This operation iterates over all the heap allocations made with () and then returns a total count, in bytes.

() iterates over all the heap allocations made with () and calls () on them. It immediately invalidates all pointers, and any subsequent reads or writes to heap memory result in undefined behavior. This is typically used at the end of the program.

() takes a pointer and fetches information about it, storing it in a structure that can then be queried.

(), (), (), and () all take in the structure returned by MemoryInfoGet(), and return the respective property about the given property. These are especially useful for logging and debugging with MemoryIterate() and MemoryHook().

() takes a pointer to a function that takes the memory information structure, as well as a void pointer for caller-provided arguments. It iterates over all the heap memory currently allocated at the time of calling. () has a similar prototype, although the function pointer it takes is slightly different. It also takes a memory action as the first argument. The Memory API stores the pointer to this function, and executes it every time memory is allocated, reallocated, or freed. This allows a program to execute code whenever memory is allocated.

() can be useful for debugging memory errors. It reads over a block of memory and generates a hexadecimal and an ASCII string for each chunk of the block. It takes a memory infomation structure and a callback function that processes the offset, hexadecimal string, and ASCII string. This callback function typically prints the strings out to a console, file, or other output device.

MemoryAllocate() and MemoryReallocate() return the same as their standard library counterparts. That is, a pointer to memory on the heap, or NULL if there was an error allocating it.

MemoryInfoGet() returns a pointer to information about a block on the heap, or NULL if the passed pointer was not allocated by the Memory API, or is no longer allocated.

MemoryAllocated() returns an unsigned integer that indicates the number of bytes currently allocated on the heap.

January 9, 2023 Telodendria Project