# HG changeset patch # User Mike Becker # Date 1737409824 -3600 # Node ID 61939929030acc528f4254661a070b37587cc805 # Parent d9ff0f091f2875fd5e520be6c2107d6ec7be76ad allocate first index buffer for strreplacen on the stack - fixes #575 diff -r d9ff0f091f28 -r 61939929030a docs/src/install.md --- a/docs/src/install.md Mon Jan 20 22:43:46 2025 +0100 +++ b/docs/src/install.md Mon Jan 20 22:50:24 2025 +0100 @@ -35,15 +35,15 @@ You can also tweak some other buffer sizes with the same technique: ---------------------------------- --------------------------------------------------- ---------- -Macro Description Default ---------------------------------- --------------------------------------------------- ---------- -CX_STRREPLACE_INDEX_BUFFER_SIZE The number of matches one index buffer can store. 64 - -CX_STREAM_COPY_BUF_SIZE The buffer size on the stack for a stream copy. 1024 - -CX_STREAM_BCOPY_BUF_SIZE The buffer size on the heap for a stream copy. 8192 ---------------------------------- --------------------------------------------------- ---------- +--------------------------------- --------------------------------------------------------------------- ---------- +Macro Description Default +--------------------------------- --------------------------------------------------------------------- ---------- +CX_STRREPLACE_INDEX_BUFFER_SIZE The number of matches the index buffer can store on the stack. 64 + +CX_STREAM_COPY_BUF_SIZE The buffer size on the stack for a stream copy. 1024 + +CX_STREAM_BCOPY_BUF_SIZE The buffer size on the heap for a stream copy. 8192 +--------------------------------- --------------------------------------------------------------------- ---------- --- diff -r d9ff0f091f28 -r 61939929030a src/string.c --- a/src/string.c Mon Jan 20 22:43:46 2025 +0100 +++ b/src/string.c Mon Jan 20 22:50:24 2025 +0100 @@ -620,6 +620,8 @@ }; static void cx_strrepl_free_ibuf(struct cx_strreplace_ibuf *buf) { + // remember, the first data is on the stack! + buf = buf->next; while (buf) { struct cx_strreplace_ibuf *next = buf->next; free(buf->buf); @@ -646,15 +648,12 @@ ibuflen = CX_STRREPLACE_INDEX_BUFFER_SIZE; } - // Allocate first index buffer - struct cx_strreplace_ibuf *firstbuf, *curbuf; - firstbuf = curbuf = calloc(1, sizeof(struct cx_strreplace_ibuf)); - if (!firstbuf) return cx_mutstrn(NULL, 0); - firstbuf->buf = calloc(ibuflen, sizeof(size_t)); - if (!firstbuf->buf) { - free(firstbuf); - return cx_mutstrn(NULL, 0); - } + // First index buffer can be on the stack + struct cx_strreplace_ibuf ibuf, *curbuf = &ibuf; + size_t ibuf_sbo[CX_STRREPLACE_INDEX_BUFFER_SIZE]; + ibuf.buf = ibuf_sbo; + ibuf.next = NULL; + ibuf.len = 0; // Search occurrences cxstring searchstr = str; @@ -667,13 +666,13 @@ struct cx_strreplace_ibuf *nextbuf = calloc(1, sizeof(struct cx_strreplace_ibuf)); if (!nextbuf) { - cx_strrepl_free_ibuf(firstbuf); + cx_strrepl_free_ibuf(&ibuf); return cx_mutstrn(NULL, 0); } nextbuf->buf = calloc(ibuflen, sizeof(size_t)); if (!nextbuf->buf) { free(nextbuf); - cx_strrepl_free_ibuf(firstbuf); + cx_strrepl_free_ibuf(&ibuf); return cx_mutstrn(NULL, 0); } curbuf->next = nextbuf; @@ -696,7 +695,7 @@ { ssize_t adjlen = (ssize_t) replacement.length - (ssize_t) pattern.length; size_t rcount = 0; - curbuf = firstbuf; + curbuf = &ibuf; do { rcount += curbuf->len; curbuf = curbuf->next; @@ -704,13 +703,13 @@ result.length = str.length + rcount * adjlen; result.ptr = cxMalloc(allocator, result.length + 1); if (!result.ptr) { - cx_strrepl_free_ibuf(firstbuf); + cx_strrepl_free_ibuf(&ibuf); return cx_mutstrn(NULL, 0); } } // Build result string - curbuf = firstbuf; + curbuf = &ibuf; size_t srcidx = 0; char *destptr = result.ptr; do { @@ -737,7 +736,7 @@ result.ptr[result.length] = '\0'; // Free index buffer - cx_strrepl_free_ibuf(firstbuf); + cx_strrepl_free_ibuf(&ibuf); return result; }