The TinyMAZEv2 Stack -------------------- TinyMAZEv2 has what I called a stack. It's not really a stack at all, but a simple memory management system. You can use the stack in a couple of different ways: 1) For temporary memory allocation. 2) For temporary and permanent memory allocation. Some of you might be wondering what I mean by temporary and permanent. A temporary memory allocation is something that you only need for a very short period of time. At the of a user command and at the end of the dispatch() call, all temporary allocations are freed. All of the memory allocation done in the TinyMAZEv2 server should be done via the stack system. Otherwise things might get quite messy. Here are the stack allocation calls: stack_alloc(unsigned long size, bool permanent, bool clear); stack_realloc(void *ptr, unsigned long size); stack_realloc_tmp(void *ptr, unsigned long size); stack_free(void *ptr); stack_free_tmp(void *ptr); stack_string_alloc(char *str, bool permanent); stack_string_realloc(void *ptr, char *str); stack_string_realloc_tmp(void *ptr, char *str); Example: Let's say you have a function that returns every other letter of the string passed to it. It would look like this: char *every_other(char *str) { static char buf[1024]; char *p, *b; for(b = buf, p = str;*p;p++) if(!((p-str) % 2)) *b++ = *p; *b = '\0'; return(buf); } The static declaration for buf is necessary because a dynamic buffer is freed as soon as the function ends and you might end up returning garbage to the calling function. However, with the stack you can eliminate the need for the static declaration with a temporary allocation call. Like this: char *every_other(char *str) { char buf[1024]; char *p, *b; for(b = buf, p = str;*p;p++) if(!((p-str) % 2)) *b++ = *p; *b = '\0'; return(stack_string_alloc(buf, 0)); } The memory allocated in this example will automatically be freed by the server. At the top of the file maze/stack.c there is a #define STACK_USAGE. There is a comment right above it explaining what different settings do. If you opt to use the stack for only temporary memory management, the server will use normal memory allocation calls when you use the stack function calls instead of reserving memory on the stack for permanent memory allocation. An indepth look at each of the stack function calls is in order: void *stack_alloc(unsigned long size, int permanent, int clear); Returns a pointer to reserved memory of 'size' bytes. 'permanent' may be 1 or 0. If it is 1, the reserved memory will not be automatically freed by the server and must be freed manually. If set to 0, the memory will be freed at the end of the user command or at the end of the dispatch() function call that happens every second. 'clear' may be 1 or 0. If set 1, the memory will be cleared (filled with 0's) making it act like a calloc() call instead of malloc(). If set to 0, the reserved memory will be left untouched. void *stack_realloc(void *ptr, unsigned long size); Returns a pointer to memory of 'size' bytes. 'ptr' must be a valid memory address returned by a previous permanent stack allocation function. The memory at 'ptr' will be resized to 'size' bytes. The contents of 'ptr' will be left untouched. If 'size' is 0, this function acts like a call to stack_free(). void *stack_realloc_tmp(void *ptr, unsigned long size); This works the same as stack_realloc() except it works on temporary allocations as well. void stack_free(void *ptr); Frees (unallocates) a chunk of memory previously reserved by another stack allocation call. If you want to free a temporary allocation you must use stack_free_tmp(). void stack_free_tmp(void *ptr); This works the same way as stack_free() except it works on temporary allocations as well. char *stack_string_alloc(char *str, int permanent); Returns a pointer to memory of strlen(str)+1 bytes. The returned pointer is filled with the contents of 'str', acting like a strdup() call. 'permanent' may be 1 or 0. If it is 1 the memory reserved will not be automatically freed by the server and must be freed manually with a stack_free() call. char *stack_string_realloc(void *ptr, char *str); This function acts like stack_realloc() except that it fills the returned pointer with the contents of 'str'. char *stack_string_realloc_tmp(void *ptr, char *str); This works the same as stack_string_realloc() except it works on temporary allocations as well. The stack system may be used as a memory leak detection system. When the system shuts down it dumps a report of the stack to the file 'run/stack_report'. For this to work properly you must have the #define STACK_USAGE at the top of 'maze/stack.c' set to 2 so the server uses the stack for permanent memory allocation.