Repository navigation
tempmem
tempmem mainly provides temporary memory for cstrings but it may also be used for other simple structs without destructor as well.
You get it with
tempstr(size)tempmem(size)dupstr(cstr)
It is not meant to store strings in a context which outlives the last tempmem save position, e.g. in a global object.
You can copy a temporary cstring into a heap-allocated string (for delete[]) using
newcopy(cstr)
IMPORTANT: You must at a low function level regularly call purge_tempmem() or the heap will fill up until you are out of memory!
tempmem is a kind of Arena memory, though it's not bound to an object but to a function. Therefore you don't need to pass in an Arena object in every allocation.
It is primarily intended to allow a function to return a cstring. As such it is a 3rd option to the c and the c++ approach:
- c: caller must provide memory to the function. e.g. snprintf(). disadvantage: caller does not know in advance how much memory is needed and tends to massively over allocate in a local variable increasing the risk of a stack overflow.
- c++: strings are always (except very short strings up to 7 chars) allocated on the heap. disadvantage: slower, leads rapidly to heap fragmentation.
tempmem uses a 'secret' buffer to allocate memory for each new string. This buffer automatically grows and yes, expands into the heap.
- disadvantage: without some active precautions you will be out of memory very soon.
Therefore the user must actively purge the tempmem buffer. There are 2 basic tools:
purge_tempmem();
This trims the tempmem buffer back to it's last 'save' state. If you haven't defined a save position, the entire buffer (of this core) is purged. Your application should contain this call at low function level in the main processing loop(s).
TempMemSave \_;
An instance of this class creates a tempmem save point in it's constructor and restores (purges) tempmem in it's destructor. Calls to purge_tempmem() during it's lifetime will only purge up to the safe position.
Functions which do a lot of string manipulations or which do some string manipulations in a loop, directly or indirectly in called functions, should create a TempMemSave and call purge_tempmem() in the loop. You can even nest them, if that makes sense.
If you want to return a temporary cstring from within a TempMemSave context, you can't do this directly. Instead you must copy it over the save position before you can return it:
return xdupstr(the_string);
This is also needed to pass the string from a local block with a TempMemSave to an outer local variable of the function. It is needed whenever you pass a string over a TempMemSave position. Caveat for nested save positions: xdupstr() only skips one save position! Also caveat: for technical reasons xdupstr() purges the tempmem (up to the save position).
This all may sound a little bit tedious, but except for the case where you want to hand out a temporary string accross a save position it is straight forward:
- at a low level regularly call purge_tempmem(). this is mandatory!
- functions which (indirectly) allocate high or unknown amount of tempmem should create a save position, preferably in functions which do not return a temporary cstring. :-)
- before calling a function which may allocate (too much) tempmem create a save position yourself.
And have a look at the heap: kilipili's malloc replacement provides a heap dump facility.