[PATCH] Make zero size allocation result consistent

Sebastian Huber sebastian.huber at embedded-brains.de
Mon May 3 07:21:32 UTC 2021


The zero size allocations had no consistent behaviour in RTEMS.  For
example, malloc( 0 ) returned NULL and posix_memalign( &p, align, 0 )
retruned in p a unique pointer (or NULL if no memory is available).  In
POSIX, zero size memory allocations are implementation-defined
behaviour.  The implementation has two options:

https://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html

https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_memalign.html

Linux and FreeBSD return a unique pointer for zero size memory
allocations.   Use this approch for RTEMS as well throughout the memory
allocation directives

Close #4390.
---
 cpukit/libcsupport/src/malloc.c          |   6 --
 cpukit/libcsupport/src/malloc_deferred.c |   4 -
 cpukit/libcsupport/src/realloc.c         |   8 +-
 testsuites/libtests/malloctest/init.c    | 106 ++++++++++++++++++++---
 4 files changed, 100 insertions(+), 24 deletions(-)

diff --git a/cpukit/libcsupport/src/malloc.c b/cpukit/libcsupport/src/malloc.c
index e61128bf8c..795254fbab 100644
--- a/cpukit/libcsupport/src/malloc.c
+++ b/cpukit/libcsupport/src/malloc.c
@@ -30,12 +30,6 @@ void *malloc(
 {
   void        *return_this;
 
-  /*
-   * Validate the parameters
-   */
-  if ( !size )
-    return (void *) 0;
-
   return_this = rtems_heap_allocate_aligned_with_boundary( size, 0, 0 );
   if ( !return_this ) {
     errno = ENOMEM;
diff --git a/cpukit/libcsupport/src/malloc_deferred.c b/cpukit/libcsupport/src/malloc_deferred.c
index b319d1213e..aab76406c7 100644
--- a/cpukit/libcsupport/src/malloc_deferred.c
+++ b/cpukit/libcsupport/src/malloc_deferred.c
@@ -106,10 +106,6 @@ void *rtems_heap_allocate_aligned_with_boundary(
 
 void *rtems_malloc( size_t size )
 {
-  if ( size == 0 ) {
-    return NULL;
-  }
-
   return rtems_heap_allocate_aligned_with_boundary( size, 0, 0 );
 }
 #endif
diff --git a/cpukit/libcsupport/src/realloc.c b/cpukit/libcsupport/src/realloc.c
index 1d9ae45c5d..e28e3fbc33 100644
--- a/cpukit/libcsupport/src/realloc.c
+++ b/cpukit/libcsupport/src/realloc.c
@@ -53,15 +53,15 @@ void *realloc( void *ptr, size_t size )
   uintptr_t           old_size;
   uintptr_t           avail_size;
 
+  if ( ptr == NULL ) {
+    return malloc( size );
+  }
+
   if ( size == 0 ) {
     free( ptr );
     return NULL;
   }
 
-  if ( ptr == NULL ) {
-    return malloc( size );
-  }
-
   heap = RTEMS_Malloc_Heap;
 
   switch ( _Malloc_System_state() ) {
diff --git a/testsuites/libtests/malloctest/init.c b/testsuites/libtests/malloctest/init.c
index 4d0f421c02..c9dcb63b2c 100644
--- a/testsuites/libtests/malloctest/init.c
+++ b/testsuites/libtests/malloctest/init.c
@@ -1153,7 +1153,10 @@ static void test_rtems_malloc(void)
   void *p;
 
   p = rtems_malloc(0);
-  rtems_test_assert(p == NULL);
+  rtems_test_assert(p != NULL);
+
+  RTEMS_OBFUSCATE_VARIABLE(p);
+  free(p);
 
   errno = 0;
   p = rtems_malloc(SIZE_MAX / 2);
@@ -1163,6 +1166,7 @@ static void test_rtems_malloc(void)
   p = rtems_malloc(1);
   rtems_test_assert(p != NULL);
 
+  RTEMS_OBFUSCATE_VARIABLE(p);
   free(p);
 }
 
@@ -1172,13 +1176,22 @@ static void test_rtems_calloc(void)
   int *i;
 
   p = rtems_calloc(0, 0);
-  rtems_test_assert(p == NULL);
+  rtems_test_assert(p != NULL);
+
+  RTEMS_OBFUSCATE_VARIABLE(p);
+  free(p);
 
   p = rtems_calloc(0, 1);
-  rtems_test_assert(p == NULL);
+  rtems_test_assert(p != NULL);
+
+  RTEMS_OBFUSCATE_VARIABLE(p);
+  free(p);
 
   p = rtems_calloc(1, 0);
-  rtems_test_assert(p == NULL);
+  rtems_test_assert(p != NULL);
+
+  RTEMS_OBFUSCATE_VARIABLE(p);
+  free(p);
 
   errno = 0;
   p = rtems_calloc(1, SIZE_MAX / 2);
@@ -1202,6 +1215,8 @@ static void test_rtems_calloc(void)
   rtems_test_assert(i != NULL);
   rtems_test_assert(*i == 0);
 
+
+  RTEMS_OBFUSCATE_VARIABLE(p);
   free(i);
 }
 
@@ -1301,6 +1316,82 @@ static void test_greedy_allocate(void)
   rtems_test_assert( p == NULL );
 }
 
+static void test_alloc_zero_size(void)
+{
+  size_t size;
+  void *p;
+  int eno;
+
+  size = 0;
+
+  RTEMS_OBFUSCATE_VARIABLE( size );
+  p = malloc( size );
+  rtems_test_assert( p != NULL );
+
+  RTEMS_OBFUSCATE_VARIABLE( p );
+  free( p );
+
+  RTEMS_OBFUSCATE_VARIABLE( size );
+  p = calloc( 1, size );
+  rtems_test_assert( p != NULL );
+
+  RTEMS_OBFUSCATE_VARIABLE( p );
+  free( p );
+
+  RTEMS_OBFUSCATE_VARIABLE( size );
+  p = rtems_malloc( size );
+  rtems_test_assert( p != NULL );
+
+  RTEMS_OBFUSCATE_VARIABLE( p );
+  free( p );
+
+  RTEMS_OBFUSCATE_VARIABLE( size );
+  p = rtems_calloc( 1, size );
+  rtems_test_assert( p != NULL );
+
+  RTEMS_OBFUSCATE_VARIABLE( p );
+  free( p );
+
+  RTEMS_OBFUSCATE_VARIABLE( size );
+  p = NULL;
+  eno = posix_memalign( &p, 32, size );
+  rtems_test_assert( eno == 0 );
+  rtems_test_assert( p != NULL );
+
+  RTEMS_OBFUSCATE_VARIABLE( p );
+  free( p );
+
+  RTEMS_OBFUSCATE_VARIABLE( size );
+  p = NULL;
+  eno = rtems_memalign( &p, 32, size );
+  rtems_test_assert( eno == 0 );
+  rtems_test_assert( p != NULL );
+
+  RTEMS_OBFUSCATE_VARIABLE( p );
+  free( p );
+
+  RTEMS_OBFUSCATE_VARIABLE( size );
+  p = aligned_alloc( 32, size );
+  rtems_test_assert( p != NULL );
+
+  RTEMS_OBFUSCATE_VARIABLE( p );
+  free( p );
+
+  RTEMS_OBFUSCATE_VARIABLE( size );
+  p = realloc( NULL, size );
+  rtems_test_assert( p != NULL );
+
+  RTEMS_OBFUSCATE_VARIABLE( p );
+  free( p );
+
+  RTEMS_OBFUSCATE_VARIABLE( size );
+  p = reallocarray( NULL, 1, size );
+  rtems_test_assert( p != NULL );
+
+  RTEMS_OBFUSCATE_VARIABLE( p );
+  free( p );
+}
+
 rtems_task Init(
   rtems_task_argument argument
 )
@@ -1327,12 +1418,6 @@ rtems_task Init(
   rtems_test_assert( p1 == NULL );
 #pragma GCC diagnostic pop
 
-  /*
-   * Verify error case where malloc of size 0.
-   */
-  p1 = malloc( 0 );
-  rtems_test_assert( p1 == NULL );
-
   test_heap_initialize();
   test_heap_block_allocate();
   test_heap_allocate();
@@ -1351,6 +1436,7 @@ rtems_task Init(
   test_rtems_malloc();
   test_rtems_calloc();
   test_greedy_allocate();
+  test_alloc_zero_size();
 
   test_posix_memalign();
 
-- 
2.26.2



More information about the devel mailing list