Tue, 15 Apr 2025 22:16:05 +0200
fixes unnecessary allocations in cx_strcat() family of functions
fixes #604
CHANGELOG | file | annotate | diff | comparison | revisions | |
docs/Writerside/topics/about.md | file | annotate | diff | comparison | revisions | |
src/string.c | file | annotate | diff | comparison | revisions |
--- a/CHANGELOG Mon Apr 14 19:53:20 2025 +0200 +++ b/CHANGELOG Tue Apr 15 22:16:05 2025 +0200 @@ -8,6 +8,7 @@ * adds cxTreeSize() * changes grow strategy for the mempory pool to reduce reallocations * changes grow strategy for CxBuffer, which does now take the page size into account + * fixes unnecessary allocations in cx_strcat() family of functions * fixes errno value after failing cxBufferSeek() to be consistently EINVAL * fixes implementation of cxBufferTerminate() * fixes allocator arguments for some printf.h functions not being const
--- a/docs/Writerside/topics/about.md Mon Apr 14 19:53:20 2025 +0200 +++ b/docs/Writerside/topics/about.md Tue Apr 15 22:16:05 2025 +0200 @@ -35,6 +35,7 @@ * adds cxTreeSize() * changes grow strategy for the mempory pool to reduce reallocations * changes grow strategy for CxBuffer, which does now take the page size into account +* fixes unnecessary allocations in cx_strcat() family of functions * fixes errno value after failing cxBufferSeek() to be consistently EINVAL * fixes implementation of cxBufferTerminate() * fixes allocator arguments for some printf.h functions not being const
--- a/src/string.c Mon Apr 14 19:53:20 2025 +0200 +++ b/src/string.c Tue Apr 15 22:16:05 2025 +0200 @@ -106,27 +106,16 @@ ... ) { if (count == 0) return str; - - cxstring strings_stack[8]; - cxstring *strings; - if (count > 8) { - strings = calloc(count, sizeof(cxstring)); - if (strings == NULL) { - return (cxmutstr) {NULL, 0}; - } - } else { - strings = strings_stack; - } - va_list ap; va_start(ap, count); + va_list ap2; + va_copy(ap2, ap); - // get all args and overall length + // compute overall length bool overflow = false; size_t slen = str.length; for (size_t i = 0; i < count; i++) { - cxstring s = va_arg (ap, cxstring); - strings[i] = s; + cxstring s = va_arg(ap, cxstring); if (slen > SIZE_MAX - str.length) overflow = true; slen += s.length; } @@ -134,10 +123,8 @@ // abort in case of overflow if (overflow) { + va_end(ap2); errno = EOVERFLOW; - if (strings != strings_stack) { - free(strings); - } return (cxmutstr) { NULL, 0 }; } @@ -149,9 +136,7 @@ newstr = cxRealloc(alloc, str.ptr, slen + 1); } if (newstr == NULL) { - if (strings != strings_stack) { - free(strings); - } + va_end(ap2); return (cxmutstr) {NULL, 0}; } str.ptr = newstr; @@ -160,19 +145,15 @@ size_t pos = str.length; str.length = slen; for (size_t i = 0; i < count; i++) { - cxstring s = strings[i]; + cxstring s = va_arg(ap2, cxstring); memcpy(str.ptr + pos, s.ptr, s.length); pos += s.length; } + va_end(ap2); // terminate string str.ptr[str.length] = '\0'; - // free temporary array - if (strings != strings_stack) { - free(strings); - } - return str; }