2 @brief lib/malloc: Wrappers and utilities for memory management.
5 Tor imposes a few light wrappers over C's native malloc and free
6 functions, to improve convenience, and to allow wholescale replacement
7 of malloc and free as needed.
9 You should never use 'malloc', 'calloc', 'realloc, or 'free' on their
10 own; always use the variants prefixed with 'tor_'.
11 They are the same as the standard C functions, with the following
14 * `tor_free(NULL)` is a no-op.
15 * `tor_free()` is a macro that takes an lvalue as an argument and sets it to
16 NULL after freeing it. To avoid this behavior, you can use `tor_free_()`
18 * tor_malloc() and friends fail with an assertion if they are asked to
19 allocate a value so large that it is probably an underflow.
20 * It is always safe to `tor_malloc(0)`, regardless of whether your libc
22 * `tor_malloc()`, `tor_realloc()`, and friends are never allowed to fail.
23 Instead, Tor will die with an assertion. This means that you never
24 need to check their return values. See the next subsection for
25 information on why we think this is a good idea.
27 We define additional general-purpose memory allocation functions as well:
29 * `tor_malloc_zero(x)` behaves as `calloc(1, x)`, except the it makes clear
30 the intent to allocate a single zeroed-out value.
31 * `tor_reallocarray(x,y)` behaves as the OpenBSD reallocarray function.
32 Use it for cases when you need to realloc() in a multiplication-safe
35 And specific-purpose functions as well:
37 * `tor_strdup()` and `tor_strndup()` behaves as the underlying libc
38 functions, but use `tor_malloc()` instead of the underlying function.
39 * `tor_memdup()` copies a chunk of memory of a given size.
40 * `tor_memdup_nulterm()` copies a chunk of memory of a given size, then
41 NUL-terminates it just to be safe.
43 #### Why assert on allocation failure?
45 Why don't we allow `tor_malloc()` and its allies to return NULL?
47 First, it's error-prone. Many programmers forget to check for NULL return
48 values, and testing for `malloc()` failures is a major pain.
50 Second, it's not necessarily a great way to handle OOM conditions. It's
51 probably better (we think) to have a memory target where we dynamically free
52 things ahead of time in order to stay under the target. Trying to respond to
53 an OOM at the point of `tor_malloc()` failure, on the other hand, would involve
54 a rare operation invoked from deep in the call stack. (Again, that's
55 error-prone and hard to debug.)
57 Third, thanks to the rise of Linux and other operating systems that allow
58 memory to be overcommitted, you can't actually ever rely on getting a NULL
59 from `malloc()` when you're out of memory; instead you have to use an approach
60 closer to tracking the total memory usage.
62 #### Conventions for your own allocation functions.
64 Whenever you create a new type, the convention is to give it a pair of
65 `x_new()` and `x_free_()` functions, named after the type.
67 Calling `x_free(NULL)` should always be a no-op.
69 There should additionally be an `x_free()` macro, defined in terms of
70 `x_free_()`. This macro should set its lvalue to NULL. You can define it
71 using the FREE_AND_NULL macro, as follows:
74 #define x_free(ptr) FREE_AND_NULL(x_t, x_free_, (ptr))