Browse Source

[core] realloc buffer power-2 size + 1 for '\0'

realloc buffer power-2 size + 1 for '\0' to avoid power-2 allocation
doubling buffer size for sole reason of storing '\0' at end of block
master
Glenn Strauss 3 months ago
parent
commit
ee9352b1bb
  1. 9
      src/buffer.c
  2. 8
      src/chunk.c

9
src/buffer.c

@ -67,6 +67,7 @@ static char* buffer_realloc(buffer * const restrict b, const size_t len) {
const size_t psz = sz;
for (sz = 256; sz < psz; sz <<= 1) ;
}
sz |= 1; /*(extra +1 for '\0' when needed buffer size is exact power-2)*/
b->size = sz;
b->ptr = realloc(b->ptr, sz);
@ -86,7 +87,8 @@ static char* buffer_alloc_replace(buffer * const restrict b, const size_t size)
b->ptr = NULL;
}
/*(note: if size larger than one lshift, use size instead of power-2)*/
return buffer_realloc(b, (b->size << 1) > size ? (b->size << 1)-1 : size);
const size_t bsize2x = (b->size & ~1uL) << 1;
return buffer_realloc(b, bsize2x > size ? bsize2x-1 : size);
}
char* buffer_string_prepare_copy(buffer * const b, const size_t size) {
@ -109,8 +111,9 @@ static char* buffer_string_prepare_append_resize(buffer * const restrict b, cons
/* not empty, b->used already includes a terminating 0 */
/*(note: if size larger than one lshift, use size instead of power-2)*/
const size_t req_size = ((b->size << 1) - b->used > size)
? (b->size << 1)-1
const size_t bsize2x = (b->size & ~1uL) << 1;
const size_t req_size = (bsize2x - b->used > size)
? bsize2x-1
: b->used + size;
/* check for overflow: unsigned overflow is defined to wrap around */

8
src/chunk.c

@ -147,7 +147,7 @@ __attribute_returns_nonnull__
static buffer * chunk_buffer_acquire_sz(size_t sz) {
chunk *c;
buffer *b;
if (sz <= chunk_buf_sz) {
if (sz <= (chunk_buf_sz|1)) {
if (chunks) {
c = chunks;
chunks = c->next;
@ -183,7 +183,7 @@ void chunk_buffer_release(buffer *b) {
chunk_buffers = c->next;
c->mem = b;
buffer_clear(b);
if (b->size == chunk_buf_sz) {
if (b->size == (chunk_buf_sz|1)) {
c->next = chunks;
chunks = c;
}
@ -215,7 +215,7 @@ size_t chunk_buffer_prepare_append(buffer * const b, size_t sz) {
__attribute_returns_nonnull__
static chunk * chunk_acquire(size_t sz) {
if (sz <= chunk_buf_sz) {
if (sz <= (chunk_buf_sz|1)) {
if (chunks) {
chunk *c = chunks;
chunks = c->next;
@ -235,7 +235,7 @@ static chunk * chunk_acquire(size_t sz) {
static void chunk_release(chunk *c) {
const size_t sz = c->mem->size;
if (sz == chunk_buf_sz) {
if (sz == (chunk_buf_sz|1)) {
chunk_reset(c);
c->next = chunks;
chunks = c;

Loading…
Cancel
Save