1libtalloc_context(3)                talloc                libtalloc_context(3)
2
3
4

NAME

6       libtalloc_context - Chapter 1: Talloc context
7
8

Talloc context

10       The talloc context is the most important part of this library and is
11       responsible for every single feature of this memory allocator. It is a
12       logical unit which represents a memory space managed by talloc.
13
14       From the programmer's point of view, the talloc context is completely
15       equivalent to a pointer that would be returned by the memory routines
16       from the C standard library. This means that every context that is
17       returned from the talloc library can be used directly in functions that
18       do not use talloc internally. For example we can do the following:
19
20       char *str1 = strdup("I am NOT a talloc context");
21       char *str2 = talloc_strdup(NULL, "I AM a talloc context");
22
23       printf("%d0, strcmp(str1, str2) == 0);
24
25       free(str1);
26       talloc_free(str2); /* we can not use free() on str2 */
27
28       This is possible because the context is internally handled as a special
29       fixed-length structure called talloc chunk. Each chunk stores context
30       metadata followed by the memory space requested by the programmer. When
31       a talloc function returns a context (pointer), it will in fact return a
32       pointer to the user space portion of the talloc chunk. If we to
33       manipulate this context using talloc functions, the talloc library
34       transforms the user-space pointer back to the starting address of the
35       chunk. This is also the reason why we were unable to use free(str2) in
36       the previous example - because str2 does not point at the beginning of
37       the allocated block of memory. This is illustrated on the next image:
38
39       The type TALLOC_CTX is defined in talloc.h to identify a talloc context
40       in function parameters. However, this type is just an alias for void
41       and exists only for semantical reasons - thus we can differentiate
42       between void * (arbitrary data) and TALLOC_CTX * (talloc context).
43
44   Context meta data
45       Every talloc context carries several pieces of internal information
46       along with the allocated memory:
47
48       • name - which is used in reports of context hierarchy and to simulate
49         a dynamic type system,
50
51       • size of the requested memory in bytes - this can be used to determine
52         the number of elements in arrays,
53
54       • attached destructor - which is executed just before the memory block
55         is about to be freed,
56
57       • references to the context
58
59       • children and parent contexts - create the hierarchical view on the
60         memory.
61

Hierarchy of talloc context

63       Every talloc context contains information about its parent and
64       children. Talloc uses this information to create a hierarchical model
65       of memory or to be more precise, it creates an n-ary tree where each
66       node represents a single talloc context. The root node of the tree is
67       referred to as a top level context - a context without any parent.
68
69       This approach has several advantages:
70
71       • as a consequence of freeing a talloc context, all of its children
72         will be properly deallocated as well,
73
74       • the parent of a context can be changed at any time, which results in
75         moving the whole subtree under another node,
76
77       • it creates a more natural way of managing data structures.
78
79   Example
80       We have a structure that stores basic information about a user -
81       his/her name, identification number and groups he/she is a member of:
82
83       struct user {
84         uid_t uid;
85         char *username;
86         size_t num_groups;
87         char **groups;
88       };
89
90       We will allocate this structure using talloc. The result will be the
91       following context tree:
92
93       /* create new top level context */
94       struct user *user = talloc(NULL, struct user);
95
96       user->uid = 1000;
97       user->num_groups = N;
98
99       /* make user the parent of following contexts */
100       user->username = talloc_strdup(user, "Test user");
101       user->groups = talloc_array(user, char*, user->num_groups);
102
103       for (i = 0; i < user->num_groups; i++) {
104         /* make user->groups the parent of following context */
105         user->groups[i] = talloc_asprintf(user->groups,
106                                           "Test group %d", i);
107       }
108
109       This way, we have gained a lot of additional capabilities, one of which
110       is very simple deallocation of the structure and all of its elements.
111
112       With the C standard library we need first to iterate over the array of
113       groups and free every element separately. Then we must deallocate the
114       array that stores them. Next we deallocate the username and as the last
115       step free the structure itself. But with talloc, the only operation we
116       need to execute is freeing the structure context. Its descendants will
117       be freed automatically.
118
119       talloc_free(user);
120

Always keep the hieararchy steady!

122       The talloc is a hierarchy memory allocator. The hierarchy nature is
123       what makes the programming more error proof. It makes the memory easier
124       to manage and to free. Therefore, the first thing we should have on our
125       mind is: always project our data structures into the talloc context
126       hierarchy.
127
128       That means if we have a structure, we should always use it as a parent
129       context for its elements. This way we will not encounter any troubles
130       when freeing this structure or when changing its parent. The same rule
131       applies for arrays.
132

Creating a talloc context

134       Here are the most important functions that create a new talloc context.
135
136   Type-safe functions
137       It allocates the size that is necessary for the given type and returns
138       a new, properly-casted pointer. This is the preferred way to create a
139       new context as we can rely on the compiler to detect type mismatches.
140
141       The name of the context is automatically set to the name of the data
142       type which is used to simulate a dynamic type system.
143
144       struct user *user = talloc(ctx, struct user);
145
146       /* initialize to default values */
147       user->uid = 0;
148       user->name = NULL;
149       user->num_groups = 0;
150       user->groups = NULL;
151
152       /* or we can achieve the same result with */
153       struct user *user_zero = talloc_zero(ctx, struct user);
154
155   Zero-length contexts
156       The zero-length context is basically a context without any special
157       semantical meaning. We can use it the same way as any other context.
158       The only difference is that it consists only of the meta data about the
159       context. Therefore, it is strictly of type TALLOC_CTX*. It is often
160       used in cases where we want to aggregate several data structures under
161       one parent (zero-length) context, such as a temporary context to
162       contain memory needed within a single function that is not interesting
163       to the caller. Allocating on a zero-length temporary context will make
164       clean-up of the function simpler.
165
166       TALLOC_CTX *tmp_ctx = NULL;
167       struct foo *foo = NULL;
168       struct bar *bar = NULL;
169
170       /* new zero-length top level context */
171       tmp_ctx = talloc_new(NULL);
172       if (tmp_ctx == NULL) {
173         return ENOMEM;
174       }
175
176       foo = talloc(tmp_ctx, struct foo);
177       bar = talloc(tmp_ctx, struct bar);
178
179       /* free everything at once */
180       talloc_free(tmp_ctx);
181
182   See also
183talloc_size()
184
185talloc_named()
186
187The talloc array functions
188
189The talloc string functions.
190
191Version 2.0                     Thu Jul 22 2021           libtalloc_context(3)
Impressum