1111#include <csnip/err.h>
1212#include <csnip/mem.h>
1313
14- void * csnip_mem_alloc (size_t n , size_t size )
14+ static inline size_t compute_alloc_amount (size_t n , size_t size )
1515{
1616 if (size != 0 && SIZE_MAX / size < n ) {
1717 /* Overflow */
18- return NULL ;
18+ return 0 ;
19+ }
20+ if ((size *= n ) == 0 ) {
21+ /* malloc() with 0 size is not guaranteed to return a
22+ * non-NULL pointer, thus we make sure we allocate
23+ * always non-zero amounts.
24+ *
25+ * Also, we use zero to signal an error.
26+ */
27+ size = 1 ;
1928 }
20- return malloc (n * size );
29+ return size ;
30+ }
31+
32+ void * csnip_mem_alloc (size_t n , size_t size )
33+ {
34+ size_t alloc_sz = compute_alloc_amount (n , size );
35+ if (alloc_sz == 0 )
36+ return NULL ;
37+ return malloc (alloc_sz );
2138}
2239
2340/* For aligned allocation, we use posix_memalign() if possible, since
@@ -31,22 +48,19 @@ void* csnip_mem_alloc(size_t n, size_t size)
3148
3249void * csnip_mem_aligned_alloc (size_t nAlign , size_t n , size_t size , int * err_ret )
3350{
34- /* Compute the allocation size, taking care of possible overflow */
35- if (size != 0 && SIZE_MAX / size < n ) {
36- if (err_ret )
37- * err_ret = csnip_err_RANGE ;
38- return NULL ;
39- }
40- size *= n ;
51+ size_t alloc_sz = compute_alloc_amount (n , size );
4152
4253#if defined(CSNIP_CONF__HAVE_POSIX_MEMALIGN ) \
4354 || !defined(CSNIP_CONF__HAVE_ALIGNED_ALLOC )
55+ if (nAlign < sizeof (void * ))
56+ nAlign *= sizeof (void * );
57+
4458 void * p_ret ;
4559#ifdef CSNIP_CONF__HAVE_POSIX_MEMALIGN
46- const int err = posix_memalign (& p_ret , nAlign , size );
60+ const int err = posix_memalign (& p_ret , nAlign , alloc_sz );
4761#else
4862 int err = 0 ;
49- p_ret = memalign (nAlign , size );
63+ p_ret = memalign (nAlign , alloc_sz );
5064 if (p_ret == NULL )
5165 err = errno ;
5266#endif
@@ -67,18 +81,18 @@ void* csnip_mem_aligned_alloc(size_t nAlign, size_t n, size_t size, int* err_ret
6781 return p_ret ;
6882#else
6983 /* use aligned_alloc() */
70- const size_t rem = size % nAlign ;
84+ const size_t rem = alloc_sz % nAlign ;
7185 if (rem != 0 ) {
7286 const size_t toadd = nAlign - rem ;
7387 /* Check for overflow */
74- if (SIZE_MAX - toadd < size ) {
88+ if (SIZE_MAX - toadd < alloc_sz ) {
7589 if (err_ret )
7690 * err_ret = csnip_err_RANGE ;
7791 return NULL ;
7892 }
79- size += toadd ;
93+ alloc_sz += toadd ;
8094 }
81- void * p_ret = aligned_alloc (nAlign , size );
95+ void * p_ret = aligned_alloc (nAlign , alloc_sz );
8296 if (p_ret == NULL && err_ret != 0 ) {
8397 if (errno == ENOMEM ) {
8498 * err_ret = csnip_err_NOMEM ;
0 commit comments