Update modules/ROOT/pages/programming-languages/C.adoc
Reserve a special section for memory leaks and automatic memory management.
This commit is contained in:
parent
001b97fc3c
commit
8b7c607f1b
1 changed files with 33 additions and 25 deletions
|
@ -551,6 +551,38 @@ free the old pointer. Therefore, the idiom `ptr =
|
||||||
realloc(ptr, size);` is wrong because the memory
|
realloc(ptr, size);` is wrong because the memory
|
||||||
pointed to by `ptr` leaks in case of an error.
|
pointed to by `ptr` leaks in case of an error.
|
||||||
|
|
||||||
|
==== Memory leaks
|
||||||
|
After a memory area has been allocated with functions like `malloc`,
|
||||||
|
`calloc`, etc. and it is no longer necessary, it must be freed in
|
||||||
|
order for the system to release the memory region and re-use it if
|
||||||
|
necessary. Failing to do so may lead to the application using more
|
||||||
|
memory than necessary and, in some cases, crashing due to no more
|
||||||
|
memory being available.
|
||||||
|
|
||||||
|
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-Use-After-Free]]
|
[[sect-Defensive_Coding-C-Use-After-Free]]
|
||||||
==== Use-after-free errors
|
==== Use-after-free errors
|
||||||
|
|
||||||
|
@ -632,7 +664,7 @@ started as a GNU extension. For large objects exceeding the
|
||||||
page size, there is no error checking, either.
|
page size, there is no error checking, either.
|
||||||
|
|
||||||
In both cases, negative or very large sizes can trigger a
|
In both cases, negative or very large sizes can trigger a
|
||||||
stack-pointer wraparound, and the stack pointer and end up
|
stack-pointer wraparound, and the stack pointer ends up
|
||||||
pointing into caller stack frames, which is fatal and can be
|
pointing into caller stack frames, which is fatal and can be
|
||||||
exploitable.
|
exploitable.
|
||||||
|
|
||||||
|
@ -644,30 +676,6 @@ Otherwise, call `malloc`. When exiting the
|
||||||
function, check if `malloc` had been called,
|
function, check if `malloc` had been called,
|
||||||
and free the buffer as needed.
|
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]]
|
[[sect-Defensive_Coding-C-Allocators-Arrays]]
|
||||||
=== Array Allocation
|
=== Array Allocation
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue