Sun, 13 May 2018 17:34:06 +0200
documentation for the UcxStack
docs/src/modules.md | file | annotate | diff | comparison | revisions | |
src/stack.c | file | annotate | diff | comparison | revisions | |
src/ucx/stack.h | file | annotate | diff | comparison | revisions |
1.1 --- a/docs/src/modules.md Sat May 12 14:56:17 2018 +0200 1.2 +++ b/docs/src/modules.md Sun May 13 17:34:06 2018 +0200 1.3 @@ -403,12 +403,55 @@ 1.4 This concrete implementation of an UCX Allocator allows you to grab some amount 1.5 of memory which is then handled as a stack. 1.6 Please note, that the term *stack* only refers to the behavior of this 1.7 -allocator. You may still choose if you want to use stack or heap memory 1.8 +allocator. You may still choose to use either stack or heap memory 1.9 for the underlying space. 1.10 - 1.11 A typical use case is an algorithm where you need to allocate and free large 1.12 amounts of memory very frequently. 1.13 1.14 +The following code sample shows how to initialize a stack and push and pop 1.15 +simple data. 1.16 +```C 1.17 + const size_t len = 1024; 1.18 + char space[len]; 1.19 + UcxStack stack; 1.20 + ucx_stack_init(&stack, space, len); 1.21 + 1.22 + int i = 42; 1.23 + float f = 3.14f; 1.24 + const char* str = "Hello!"; 1.25 + size_t strn = 7; 1.26 + 1.27 + /* push the integer */ 1.28 + ucx_stack_push(&stack, sizeof(int), &i); 1.29 + 1.30 + /* push the float and rember the address */ 1.31 + float* remember = ucx_stack_push(&stack, sizeof(float), &f); 1.32 + 1.33 + /* push the string with zero terminator */ 1.34 + ucx_stack_push(&stack, strn, str); 1.35 + 1.36 + /* if we forget, how big an element was, we can ask the stack */ 1.37 + printf("Length of string: %zu\n", ucx_stack_topsize(&stack)-1); 1.38 + 1.39 + /* retrieve the string as sstr_t, without zero terminator! */ 1.40 + sstr_t s; 1.41 + s.length = ucx_stack_topsize(&stack)-1; 1.42 + s.ptr = malloc(s.length); 1.43 + ucx_stack_popn(&stack, s.ptr, s.length); 1.44 + printf("%" PRIsstr "\n", SFMT(s)); 1.45 + 1.46 + /* print the float directly from the stack and free it */ 1.47 + printf("Float: %f\n", *remember); 1.48 + ucx_stack_free(&stack, remember); 1.49 + 1.50 + /* the last element is the integer */ 1.51 + int j; 1.52 + ucx_stack_pop(&stack, &j); 1.53 + printf("Integer: %d\n", j); 1.54 +``` 1.55 + 1.56 + 1.57 + 1.58 ## String 1.59 1.60 *Header file:* [string.h](api/string_8h.html)
2.1 --- a/src/stack.c Sat May 12 14:56:17 2018 +0200 2.2 +++ b/src/stack.c Sun May 13 17:34:06 2018 +0200 2.3 @@ -120,13 +120,15 @@ 2.4 return; 2.5 } 2.6 2.7 - size_t len = ucx_stack_topsize(stack); 2.8 - if (len > n) { 2.9 - len = n; 2.10 + if (dest) { 2.11 + size_t len = ucx_stack_topsize(stack); 2.12 + if (len > n) { 2.13 + len = n; 2.14 + } 2.15 + 2.16 + memcpy(dest, stack->top, len); 2.17 } 2.18 2.19 - memcpy(dest, stack->top, len); 2.20 - 2.21 ucx_stack_free(stack, stack->top); 2.22 } 2.23 2.24 @@ -142,3 +144,22 @@ 2.25 return 0; 2.26 } 2.27 } 2.28 + 2.29 +void *ucx_stack_push(UcxStack *stack, size_t n, const void *data) { 2.30 + void *space = ucx_stack_malloc(stack, n); 2.31 + if (space) { 2.32 + memcpy(space, data, n); 2.33 + } 2.34 + return space; 2.35 +} 2.36 + 2.37 +void *ucx_stack_pusharr(UcxStack *stack, 2.38 + size_t nelem, size_t elsize, const void *data) { 2.39 + 2.40 + // skip the memset by using malloc 2.41 + void *space = ucx_stack_malloc(stack, nelem*elsize); 2.42 + if (space) { 2.43 + memcpy(space, data, nelem*elsize); 2.44 + } 2.45 + return space; 2.46 +}
3.1 --- a/src/ucx/stack.h Sat May 12 14:56:17 2018 +0200 3.2 +++ b/src/ucx/stack.h Sun May 13 17:34:06 2018 +0200 3.3 @@ -91,19 +91,23 @@ 3.4 * 3.5 * @param stack a pointer to the stack 3.6 * @param n amount of memory to allocate 3.7 - * @return a pointer to the allocated memory 3.8 + * @return a pointer to the allocated memory or <code>NULL</code> on stack 3.9 + * overflow 3.10 * @see ucx_allocator_malloc() 3.11 */ 3.12 void *ucx_stack_malloc(UcxStack *stack, size_t n); 3.13 3.14 /** 3.15 - * Alias for #ucx_stack_malloc(). 3.16 + * Allocates memory with #ucx_stack_malloc() and copies the specified data if 3.17 + * the allocation was successful. 3.18 + * 3.19 * @param stack a pointer to the stack 3.20 * @param n amount of memory to allocate 3.21 + * @param data a pointer to the data to copy 3.22 * @return a pointer to the allocated memory 3.23 * @see ucx_stack_malloc 3.24 */ 3.25 -#define ucx_stack_push(stack, n) ucx_stack_malloc(stack, n) 3.26 +void *ucx_stack_push(UcxStack *stack, size_t n, const void *data); 3.27 3.28 /** 3.29 * Allocates an array of stack memory 3.30 @@ -119,15 +123,18 @@ 3.31 void *ucx_stack_calloc(UcxStack *stack, size_t nelem, size_t elsize); 3.32 3.33 /** 3.34 - * Alias for #ucx_stack_calloc(). 3.35 + * Allocates memory with #ucx_stack_calloc() and copies the specified data if 3.36 + * the allocation was successful. 3.37 * 3.38 * @param stack a pointer to the stack 3.39 - * @param n amount of elements to allocate 3.40 + * @param nelem amount of elements to allocate 3.41 * @param elsize amount of memory per element 3.42 + * @param data a pointer to the data 3.43 * @return a pointer to the allocated memory 3.44 * @see ucx_stack_calloc 3.45 */ 3.46 -#define ucx_stack_pusharr(stack,n,elsize) ucx_stack_calloc(stack,n,elssize) 3.47 +void *ucx_stack_pusharr(UcxStack *stack, 3.48 + size_t nelem, size_t elsize, const void *data); 3.49 3.50 /** 3.51 * Reallocates memory on the stack. 3.52 @@ -184,12 +191,13 @@ 3.53 * Removes the top most element from the stack and copies the content to <code> 3.54 * dest</code>. 3.55 * 3.56 - * In contrast to #ucx_stack_pop() the <code>dest</code> pointer <code>MUST 3.57 - * NOT</code> be <code>NULL</code>. 3.58 + * This function copies at most <code>n</code> bytes to the destination, but 3.59 + * the element is always freed as a whole. 3.60 + * If the element was larger than <code>n</code>, the remaining data is lost. 3.61 * 3.62 * @param stack a pointer to the stack 3.63 * @param dest the location where the contents shall be written to 3.64 - * @param n copies at most n elements to <code>dest</code> 3.65 + * @param n copies at most n bytes to <code>dest</code> 3.66 * @see ucx_stack_pop 3.67 */ 3.68 void ucx_stack_popn(UcxStack *stack, void *dest, size_t n);