Search notes:

libc: Memory allocation

In C, there are two ways to allocate memory; static allocation and automatic allocation. The libc memory allocation functions provide a third way to allocate memory: dynamic memory allocation.

malloc

malloc(n) allocates n bytes of uninitialized memory (or a null pointer if not sufficient memory could be allocated).
The return type of malloc is void* which can be converted to any other pointer type in ISO C (but apparently not in traditional C).
#include <stdio.h>
#include <stdlib.h>

int main() {

  void* mem_1 = malloc(0xff);
  void* mem_2 = malloc(0xff);
  void* mem_3 = malloc(0xff);

  printf("%llx\n", mem_1);
  printf("%llx\n", mem_2);
  printf("%llx\n", mem_3);

  free(mem_1);
  free(mem_2);
  free(mem_3);

}
Github repository about-libc, path: /alloc/malloc.c
In Linux, malloc uses brk to grow a process's data segment.
Apparently, there is also possibility to map /dev/zero to get anonymous memory.

alloc

alloc() is a BSD extansion. It allocates memory on the stack.
alloc() comes in handy when used in conjunction with longjmp().

mtrace

mtrace() traces function calls to malloc(), realloc() and free and protocolls them into the file pointed at with the environment variable MALLOC_TRACE (at runtime, not at compile time). Thus, it is possible to detect memory leaks.
The protocol can then be analysed with the mtrace binary.
#include <stdlib.h>
#include <mcheck.h>

int main() {

    mtrace();

    void *mem_1 = malloc( 500);
    void *mem_2 = malloc(1000);

    free(mem_1); // Note mem_1 is freed twice,
    free(mem_1); // mem_2 is not freed at all

}
Github repository about-libc, path: /alloc/mtrace.c
With the program above, one might do
$ gcc mtrace.c -o mt
$ MALLOC_TRACE=/tmp/mtrace.out ./mt
$ mtrace /tmp/mtrace.out
The result is then something like
- 0x000055c5744986a0 Free 5 was never alloc'd 0x55c573a2319a

Memory not freed:
-----------------
           Address     Size     Caller
0x000055c5744988a0    0x3e8  at 0x55c573a2317e

mcheck

#include <stdlib.h>
#include <stdio.h>
#include <mcheck.h>

void mcheck_callback(enum mcheck_status status) {

     printf("memcheck_abort: status = ");

     if      (status == MCHECK_DISABLED) printf("MCHECK_DISABLED");
     else if (status == MCHECK_OK      ) printf("MCHECK_OK"      );
     else if (status == MCHECK_HEAD    ) printf("MCHECK_HEAD"    );
     else if (status == MCHECK_TAIL    ) printf("MCHECK_TAIL"    );
     else if (status == MCHECK_FREE    ) printf("MCHECK_FREE"    );

     printf("\n");

}

int main() {

    mcheck(mcheck_callback);

    char *m1 = malloc( 50);
    char *m2 = malloc(150);

    printf("Free 1st time\n");
    free(m1);

    printf("Free 2nd time\n");
    free(m1);

    printf("The END.\n");
}
Github repository about-libc, path: /alloc/mcheck.c

TODO

calloc, alloca, aligned_alloc, posix_memalign.
mallinfo
-lmcheck (linker)

See also

The Standard C Library
Valgrind

Index