Merge #13 Add some tips to C-Allocators

This commit is contained in:
Huzaifa Sidhpurwala 2020-10-13 10:16:59 +00:00
commit 0888d3db13

View file

@ -43,6 +43,20 @@ compiler may assume that a comparison between the old and new
pointer will always return false, so it is impossible to detect
movement this way.
On a related note, `realloc` frees the memory area if the new size is
zero. If the size unintentionally becomes zero, as a result of
unsigned integer wrap-around for instance, the following idiom causes
a double-free.
[source,c]
----
new_size = size + x; /* 'x' is a very large value and the result wraps around to zero */
new_ptr = realloc(ptr, new_size);
if (!new_ptr) {
free(ptr);
}
----
==== Handling Memory Allocation Errors
Recovering from out-of-memory errors is often difficult or even
@ -105,6 +119,30 @@ Otherwise, call `malloc`. When exiting the
function, check if `malloc` had been called,
and free the buffer as needed.
If portability is not important in your program, an alternative way of
automatic memory management is to leverage the `cleanup` attribute
supported by the recent versions of GCC and Clang. If a local variable
is declared with the attribute, the specified cleanup function will be
called when the variable goes out of scope.
[source,c]
----
static inline void freep(void *p) {
free(*(void**) p);
}
void somefunction(const char *param) {
if (strcmp(param, "do_something_complex") == 0) {
__attribute__((cleanup(freep))) char *ptr = NULL;
/* Allocate a temporary buffer */
ptr = malloc(size);
/* Do something on it, but do not need to manually call free() */
}
}
----
[[sect-Defensive_Coding-C-Allocators-Arrays]]
=== Array Allocation
@ -118,6 +156,12 @@ to allocate an array of `n` elements of type
greater than `((size_t) -1) / sizeof(T)`. See
<<sect-Defensive_Coding-C-Arithmetic>>.
GNU libc provides a dedicated function `reallocarray` that allocates
an array with those checks performed internally. However, care must
be taken if portability is important: while the interface originated
in OpenBSD and has been adopted in many other platforms, NetBSD
exposes an incompatible behavior with the same interface.
[[sect-Defensive_Coding-C-Allocators-Custom]]
=== Custom Memory Allocators