1libtalloc_context(3Version) libtalloc_context(3Version)
2
3
4
6 libtalloc_context - Chapter 1: Talloc context
7
9 The talloc context is the most important part of this library and is
10 responsible for every single feature of this memory allocator. It is a
11 logical unit which represents a memory space managed by talloc.
12
13 From the programmer's point of view, the talloc context is completely
14 equivalent to a pointer that would be returned by the memory routines
15 from the C standard library. This means that every context that is
16 returned from the talloc library can be used directly in functions that
17 do not use talloc internally. For example we can do the following:
18
19 char *str1 = strdup("I am NOT a talloc context");
20 char *str2 = talloc_strdup(NULL, "I AM a talloc context");
21
22 printf("%d\n", strcmp(str1, str2) == 0);
23
24 free(str1);
25 talloc_free(str2); /* we can not use free() on str2 */
26
27 This is possible because the context is internally handled as a special
28 fixed-length structure called talloc chunk. Each chunk stores context
29 metadata followed by the memory space requested by the programmer. When
30 a talloc function returns a context (pointer), it will in fact return a
31 pointer to the user space portion of the talloc chunk. If we to
32 manipulate this context using talloc functions, the talloc library
33 transforms the user-space pointer back to the starting address of the
34 chunk. This is also the reason why we were unable to use free(str2) in
35 the previous example - because str2 does not point at the beginning of
36 the allocated block of memory. This is illustrated on the next image:
37
38 The type TALLOC_CTX is defined in talloc.h to identify a talloc context
39 in function parameters. However, this type is just an alias for void
40 and exists only for semantical reasons - thus we can differentiate
41 between void * (arbitrary data) and TALLOC_CTX * (talloc context).
42
43 Context meta data
44 Every talloc context carries several pieces of internal information
45 along with the allocated memory:
46
47 • name - which is used in reports of context hierarchy and to simulate
48 a dynamic type system,
49
50 • size of the requested memory in bytes - this can be used to determine
51 the number of elements in arrays,
52
53 • attached destructor - which is executed just before the memory block
54 is about to be freed,
55
56 • references to the context
57
58 • children and parent contexts - create the hierarchical view on the
59 memory.
60
62 Every talloc context contains information about its parent and
63 children. Talloc uses this information to create a hierarchical model
64 of memory or to be more precise, it creates an n-ary tree where each
65 node represents a single talloc context. The root node of the tree is
66 referred to as a top level context - a context without any parent.
67
68 This approach has several advantages:
69
70 • as a consequence of freeing a talloc context, all of its children
71 will be properly deallocated as well,
72
73 • the parent of a context can be changed at any time, which results in
74 moving the whole subtree under another node,
75
76 • it creates a more natural way of managing data structures.
77
78 Example
79 We have a structure that stores basic information about a user -
80 his/her name, identification number and groups he/she is a member of:
81
82 struct user {
83 uid_t uid;
84 char *username;
85 size_t num_groups;
86 char **groups;
87 };
88
89 We will allocate this structure using talloc. The result will be the
90 following context tree:
91
92 /* create new top level context */
93 struct user *user = talloc(NULL, struct user);
94
95 user->uid = 1000;
96 user->num_groups = N;
97
98 /* make user the parent of following contexts */
99 user->username = talloc_strdup(user, "Test user");
100 user->groups = talloc_array(user, char*, user->num_groups);
101
102 for (i = 0; i < user->num_groups; i++) {
103 /* make user->groups the parent of following context */
104 user->groups[i] = talloc_asprintf(user->groups,
105 "Test group %d", i);
106 }
107
108 This way, we have gained a lot of additional capabilities, one of which
109 is very simple deallocation of the structure and all of its elements.
110
111 With the C standard library we need first to iterate over the array of
112 groups and free every element separately. Then we must deallocate the
113 array that stores them. Next we deallocate the username and as the last
114 step free the structure itself. But with talloc, the only operation we
115 need to execute is freeing the structure context. Its descendants will
116 be freed automatically.
117
118 talloc_free(user);
119
121 The talloc is a hierarchy memory allocator. The hierarchy nature is
122 what makes the programming more error proof. It makes the memory easier
123 to manage and to free. Therefore, the first thing we should have on our
124 mind is: always project our data structures into the talloc context
125 hierarchy.
126
127 That means if we have a structure, we should always use it as a parent
128 context for its elements. This way we will not encounter any troubles
129 when freeing this structure or when changing its parent. The same rule
130 applies for arrays.
131
133 Here are the most important functions that create a new talloc context.
134
135 Type-safe functions
136 It allocates the size that is necessary for the given type and returns
137 a new, properly-casted pointer. This is the preferred way to create a
138 new context as we can rely on the compiler to detect type mismatches.
139
140 The name of the context is automatically set to the name of the data
141 type which is used to simulate a dynamic type system.
142
143 struct user *user = talloc(ctx, struct user);
144
145 /* initialize to default values */
146 user->uid = 0;
147 user->name = NULL;
148 user->num_groups = 0;
149 user->groups = NULL;
150
151 /* or we can achieve the same result with */
152 struct user *user_zero = talloc_zero(ctx, struct user);
153
154 Zero-length contexts
155 The zero-length context is basically a context without any special
156 semantical meaning. We can use it the same way as any other context.
157 The only difference is that it consists only of the meta data about the
158 context. Therefore, it is strictly of type TALLOC_CTX*. It is often
159 used in cases where we want to aggregate several data structures under
160 one parent (zero-length) context, such as a temporary context to
161 contain memory needed within a single function that is not interesting
162 to the caller. Allocating on a zero-length temporary context will make
163 clean-up of the function simpler.
164
165 TALLOC_CTX *tmp_ctx = NULL;
166 struct foo *foo = NULL;
167 struct bar *bar = NULL;
168
169 /* new zero-length top level context */
170 tmp_ctx = talloc_new(NULL);
171 if (tmp_ctx == NULL) {
172 return ENOMEM;
173 }
174
175 foo = talloc(tmp_ctx, struct foo);
176 bar = talloc(tmp_ctx, struct bar);
177
178 /* free everything at once */
179 talloc_free(tmp_ctx);
180
181 See also
182 • talloc_size()
183
184 • talloc_named()
185
186 • The talloc array functions
187
188 • The talloc string functions.
189
190talloc 2.0" libtalloc_context(3Version)