Fix realloc() with size 0
Valgrind reported “realloc() with size 0"
'''
==508== realloc() with size 0
==508== at 0x484DB80: realloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==508== by 0x1093E3: ringbuffer_consumer_unregister (ringbuffer.c:103)
==508== by 0x10942B: ringbuffer_fini (ringbuffer.c:48)
==508== by 0x109989: test_simple_poll (test-ringbuffer-simple-poll.c:31)
==508== by 0x109A3A: main (test-ringbuffer-simple-poll.c:37)
'''
And gnu libc manual[1] said:
Portable programs should not attempt to reallocate blocks to be size
zero. On other implementations if ptr is non-null, realloc (ptr, 0)
might free the block and return a non-null pointer to a size-zero
object, or it might fail and return NULL without freeing the block.
The ISO C17 standard allows these variations.
So use free instead of realloc with size 0
[1] https://www.gnu.org/software/libc/manual/html_node/Changing-Block-Size.html
Change-Id: Ie716dd6ea84696a2091c680d71a0624423d1a185
Signed-off-by: John Wang <wangzhiqiang02@ieisystem.com>
diff --git a/ringbuffer.c b/ringbuffer.c
index 13104e9..4c4397b 100644
--- a/ringbuffer.c
+++ b/ringbuffer.c
@@ -96,13 +96,19 @@
* We're managing an array of pointers to aggregates, so don't warn about sizeof() on a
* pointer type.
*/
- /* NOLINTBEGIN(bugprone-sizeof-expression) */
memmove(&rb->consumers[i], &rb->consumers[i + 1],
+ /* NOLINTNEXTLINE(bugprone-sizeof-expression) */
sizeof(*rb->consumers) * (rb->n_consumers - i));
- rb->consumers = reallocarray(rb->consumers, rb->n_consumers,
- sizeof(*rb->consumers));
- /* NOLINTEND(bugprone-sizeof-expression) */
+ if (rb->n_consumers == 0) {
+ free(rb->consumers);
+ rb->consumers = NULL;
+ } else {
+ rb->consumers = reallocarray(
+ rb->consumers, rb->n_consumers,
+ /* NOLINTNEXTLINE(bugprone-sizeof-expression) */
+ sizeof(*rb->consumers));
+ }
free(rbc);
}