# Binutils Libiberty: `objalloc`
## Introduction
There is a small library in libiberty called **objalloc**. It is a memory management tool that an "object" can be used to simplify space allocation. An "object" can be any kind of data structure implementation, for example, a list that the elements are pointers points to dynamically allocated spaces. We will have a little pseudo code example in the following sections.
**objalloc** assumes:
> ... that the object will want to allocate space as it goes along, but will never want to free any particular block.
The source code for the **objalloc** is pretty simple, only about 400 lines of code in the 2 files:
* *[include/objalloc.h](https://github.com/bminor/binutils-gdb/blob/master/include/objalloc.h)*
* *[libiberty/objalloc.c](https://github.com/bminor/binutils-gdb/blob/master/libiberty/objalloc.c)*
## Example
Let's implement a list structure. The list provides only simple interfaces:
* Create a list
* Append a string to the list
* Print the entries of the list
* Free the memory allocated in the list
When the list is created, all the entires are NULL pointers. To append a new entry, the list allocates a memory and we can first create an `struct objalloc` with `objallo_create()`, and use `objalloc_alloc()` to allocate a memory space for the new entry. When it's time to cleanup memories, we can call `objallo_free()` on the `struct objalloc` we created earlier.
The full example code can be found in the Github repo:
https://github.com/hauhsu/libiberty-objalloc-example
### Defining `struct list`
The struct defines a list of strings (`chat *`) pointers, the size of the list, the last used index and the memory space to store the contents:
```c
struct list
{
char **entry;
int size;
int last_index;
struct objalloc *memory;
};
```
Note that the `memory` field is managed by an `objalloc`, and the `**entry` is an string array that will point to the memories allocated by the `objalloc`.
### Creating a list
The function to create a list looks like:
``` c
struct list* list_create(int size)
{
struct list *ret = malloc(sizeof(struct list));
if (ret == NULL)
return NULL;
ret->size = size;
ret->last_index = -1;
ret->memory = objalloc_create(); /* Use objallo for memory management. */
ret->entry = objalloc_alloc(ret->memory, sizeof(void*) * size);
return ret;
}
```
As you can see, we created an `objalloc` with `objallo_create()` and use it to allocate
memory for our `entry`.
### Appending a string to a list
To append a string to a list, we need to check whether the list is alyready full:
``` c
bool list_append(struct list *l, const char* str)
{
if (l->last_index == l->size-1)
return false;
...
}
```
If there are still spaces, use `objalloc_alloc()` to acquire a space for the string,
and use `memcpy` to copy the characters into the newly allocated memory:
```c
...
l->last_index ++;
l->entry[l->last_index] = objalloc_alloc(l->memory, strlen(str));
strcpy(l->entry[l->last_index], str);
return true;
}
```
### Freeing a list
This is the whole point of using `objalloc`. With `objallo`, we don't have to iterate
over the entry, but using `objalloc_free` to free the `memory` field. `objalloc` will
handle the dirty work for us:
```
void list_free(struct list *l)
{
objalloc_free(l->memory);
free(l->entry);
free(l);
}
```
## Build and run
Here are the simple commands to build and run the example:
```
$ gcc *.c -o list
$ ./list
list[0] = hello
list[1] = world
```