libacfutils
A general purpose library of utility functions designed to make it easier to develop addons for the X-Plane flight simulator.
Loading...
Searching...
No Matches
Macros | Functions
safe_alloc.h File Reference
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include "assert.h"
#include "sysmacros.h"
Include dependency graph for safe_alloc.h:

Go to the source code of this file.

Macros

#define ZERO_FREE(ptr)
 
#define DESTROY_FREE(ptr)
 
#define ZERO_FREE_N(ptr, num)
 
#define DESTROY_FREE_N(ptr, num)
 
#define BZERO(data)   memset((data), 0, sizeof (*(data)))
 
#define SAFE_BZERO(data)
 

Functions

static void * safe_malloc (size_t size)
 
static void * safe_calloc (size_t nmemb, size_t size)
 
static void * safe_realloc (void *oldptr, size_t size)
 
static void * safe_aligned_malloc (size_t alignment, size_t size)
 
static void * safe_aligned_calloc (size_t alignment, size_t nmemb, size_t size)
 
static void aligned_free (void *ptr)
 
static char * safe_strdup (const char *str2)
 
static char * safe_append_realloc (char *buf, const char *str)
 

Macro Definition Documentation

◆ BZERO

#define BZERO (   data)    memset((data), 0, sizeof (*(data)))

Performs a zeroing of the data buffer. Please note that sizeof must return the correct size of the data to be zeroed. Thus this is intended to be used fixed-size arrays.

Definition at line 296 of file safe_alloc.h.

◆ DESTROY_FREE

#define DESTROY_FREE (   ptr)
Value:
do { \
ZERO_FREE(ptr); \
(ptr) = NULL; \
} while (0)

Same as ZERO_FREE(), but also sets ptr to NULL after freeing.

Definition at line 264 of file safe_alloc.h.

◆ DESTROY_FREE_N

#define DESTROY_FREE_N (   ptr,
  num 
)
Value:
do { \
ZERO_FREE_N((ptr), (num)); \
(ptr) = NULL; \
while (0)

Same as ZERO_FREE_N(), but also sets ptr to NULL after freeing.

Definition at line 285 of file safe_alloc.h.

◆ SAFE_BZERO

#define SAFE_BZERO (   data)
Value:
do { \
if ((data) != NULL) \
BZERO(data); \
} while (0)

If data is not NULL, performs a BZERO on the data.

Definition at line 301 of file safe_alloc.h.

◆ ZERO_FREE

#define ZERO_FREE (   ptr)
Value:
do { \
NOT_TYPE_ASSERT(ptr, void *); \
NOT_TYPE_ASSERT(ptr, char *); \
if ((ptr) != NULL) \
memset((ptr), 0, sizeof (*(ptr))); \
free(ptr); \
} while (0)

If ptr is not a NULL pointer, the contained data is first zeroed, and subsequently deallocated using free(). This is useful for making sure nothing remains of a buffer after freeing, thus preventing potentially attempting to read its contents and seeing valid data (use-after-free).

N.B. this macro relies on sizeof returning the correct size of this data buffer, so it should only be used on single struct buffers, not arrays.

Definition at line 253 of file safe_alloc.h.

◆ ZERO_FREE_N

#define ZERO_FREE_N (   ptr,
  num 
)
Value:
do { \
NOT_TYPE_ASSERT(ptr, void *); \
if ((ptr) != NULL) \
memset((ptr), 0, sizeof (*(ptr)) * (num)); \
free(ptr); \
} while (0)

Same as ZERO_FREE, but takes an explicit array element count argument. This is the variant of the ZERO_FREE macro to be used on arrays of objects, rather than single objects.

Definition at line 275 of file safe_alloc.h.

Function Documentation

◆ aligned_free()

static void aligned_free ( void *  ptr)
static

Frees memory previously allocated using safe_aligned_malloc() or safe_aligned_calloc().

Note
You must NOT use the normal C library free() function, as doing so is NOT portable.

Definition at line 181 of file safe_alloc.h.

◆ safe_aligned_calloc()

static void * safe_aligned_calloc ( size_t  alignment,
size_t  nmemb,
size_t  size 
)
static

Same as safe_calloc(), but allows you to specify an alignment requirement for the buffer.

Parameters
alignmentThe byte alignment of the buffer. This must be a power-of-two and no smaller than sizeof (void *).
Returns
If successful, the returned address is guaranteed to be aligned to multiples of alignment bytes. The contents of the memory buffer are zero-initialized. The returned pointer must be passed to aligned_free() to dispose of the allocation and avoid leaking memory.
Note
You must NOT use the normal C library free() function, as doing so is NOT portable.
Returns
If the memory allocation cannot be satisfied, this function triggers an assertion failure with an out-of-memory error.
Note
If the requested buffer size is 0, this function may return NULL, or an unusable non-NULL pointer which is safe to pass to free().

Definition at line 167 of file safe_alloc.h.

◆ safe_aligned_malloc()

static void * safe_aligned_malloc ( size_t  alignment,
size_t  size 
)
static

Same as safe_malloc(), but allows you to specify an alignment requirement for the buffer.

Parameters
alignmentThe byte alignment of the buffer. This must be a power-of-two and no smaller than sizeof (void *).
Returns
If successful, the returned address is guaranteed to be aligned to multiples of alignment bytes. The contents of the memory buffer are undefined. The returned pointer must be passed to aligned_free() to dispose of the allocation and avoid leaking memory.
Note
You must NOT use the normal C library free() function, as doing so is NOT portable.
Returns
If the memory allocation cannot be satisfied, this function triggers an assertion failure with an out-of-memory error.
Note
If the requested buffer size is 0, this function may return NULL, or an unusable non-NULL pointer which is safe to pass to free().

Definition at line 119 of file safe_alloc.h.

◆ safe_append_realloc()

static char * safe_append_realloc ( char *  buf,
const char *  str 
)
static

Concatenates str onto the end of buf, enlarging it as necessary. If memory cannot be allocated to hold the new string, this crashes with an assertion failure. This is using the safe_malloc() machinery underneath, so all the same rules apply.

Parameters
bufBuffer to append to. If this argument is NULL, a new buffer is allocated. Otherwise, the buffer is safe_realloc()d to contain the new concatenated string.
strThe input string to append onto the end of buf. This must NOT be NULL.
Returns
The new combined buffer holding a concatenation of buf and str. Please note that since reallocation may occur, you must not reuse the old buf pointer value after calling safe_append_realloc(). You should reassign the pointer using the return value of this function.

Definition at line 230 of file safe_alloc.h.

◆ safe_calloc()

static void * safe_calloc ( size_t  nmemb,
size_t  size 
)
static

Same as safe_malloc(), except it calls calloc() on the back-end and behaves exactly the standard calloc() function.

Definition at line 71 of file safe_alloc.h.

◆ safe_malloc()

static void * safe_malloc ( size_t  size)
static

Provides a front-end to your compiler's malloc() function, but with automated allocation success checking. In general, you can just replace any calls to malloc() with calls to safe_malloc() and it will work exactly the same, except in cases where the allocation fails. If the allocation fails, this generates an assertion failure crash with a diagnostic message telling you how many byte failed to be allocated.

N.B. unlike any allocation that you might get returned from within libacfutils, which you should free using lacf_free(), the pointer returned from this function is allocated your compiler's allocator. Thus you MUST use your normal free() function to free this one.

Definition at line 56 of file safe_alloc.h.

◆ safe_realloc()

static void * safe_realloc ( void *  oldptr,
size_t  size 
)
static

Same as safe_malloc(), except it calls realloc() on the back-end and behaves exactly the standard realloc() function.

Definition at line 86 of file safe_alloc.h.

◆ safe_strdup()

static char * safe_strdup ( const char *  str2)
static

Provides an allocation-safe version of strdup(). If the allocation of the required number of bytes fails, this trips an assertion check and causes the application to crash due to having run out of memory.

Definition at line 201 of file safe_alloc.h.