2020-08-20

c memory management

free current memory allocations at point

by tracking allocations locally

example

this example uses a reference implementation from sph-sc-lib. sph-sc-lib also contains a version with multiple named registers and a register to be passed between routines.

  • memreg_init(4) creates an address register on the stack for at most four pointers
  • memreg_register is the variable and memreg_index is the current index
  • memreg_add(address) adds a pointer to the register
  • memreg_free frees all pointers added so far
#include "sph/memreg.c"
int main() {
  memreg_init(2);
  int* data_a = malloc(12 * sizeof(int));
  if(!data_a) goto exit;  // have to free nothing
  memreg_add(data_a);
  // more code ...
  char* data_b = malloc(20 * sizeof(char));
  if(!data_b) goto exit;  // have to free "data_a"
  memreg_add(data_b);
  // ...
  if (is_error) goto exit;  // have to free "data_a" and "data_b"
  // ...
exit:
  memreg_free;
  return(0);
}

ownership

it might be helpful to think in terms of ownership: the function that is the current owner is responsible for allocation and deallocation. ownership can be passed over, received and memory can also be lend

memory leaks

  • heap memory is requested when needed and then gets reserved for the program (allocation). if the reservation is not ended when the memory is not needed anymore (deallocation), then the memory will stay reserved unusable for the program and the memory consumption of a process can grow continually over time with more allocations. this is called memory leak
  • it prevents programs from running for an indefinite amount of time
  • each allocation must, as some point in the execution, be followed by a deallocation. all memory is released implicitly with the end of the process
  • tools like valgrind can help to trace and find memory leaks

null pointers

a pointer is a variable that stores a memory address. a null pointer can be created with setting a pointer to zero. calling free on a null pointer is usually allowed, but trying to use such a pointer leads to an error

double free and corruption

  • calling free on a pointer whose address has previously been freed is an error
  • memory corruption can occur when the program haphazardly wrote into the memory outside of the allocated range. this can mess up management structures of the allocator and is a common attack area for security exploits

heap and stack

the stack is memory space that is reserved for the extent of a routine call, for example to store routine arguments and local variables. it has a pre-calculated, limited or fixed size. heap memory is the available system random access memory. variables with stack memory only need to be declared, variables with heap memory need to be declared as pointers and the heap memory separately allocated. heap allocation and deallocation can be seen as side-effecting processes like accessing a database.

life time

  • the c compiler has no indication of when memory is not needed anymore. how long a memory area is needed may depend on various application conditions. references to memory areas can be passed between and persist between routine calls. memory stays allocated even if no variable has a reference to it
  • at allocation, decide when the memory is going to be freed. in the successful execution flow as well as when errors occur