Sometimes you will need to allocate memory spaces in the heap also known as the dynamic memory. This is particularly useful when you do not know during compile time how large a data structure (like an array) will be.
The magic function here is the `malloc` which will return as output a void pointer (it is a pointer to a region of unknown data type) to the new memory space we've just allocated.
Let's start from `sizeof`, a sweet C macro. `malloc` only cares about memory, and thus allocates the number of bytes you ask it. Not the number of `int`s or `float`s, **the number of bytes**. But how do you _know_ how many bytes a given type needs?
Enter the `sizeof` macro.
**Note:** Never assume the size a type needs since they can change based on implementation and system.
Here, malloc takes the number of bytes we want (the size of an `int` multiplied by how many of them we want) and gives us a pointer to a memory block with at least that much space ... most of the time. If we run out of memory (or some other error occurs), `malloc` returns `NULL`!
### Checking the malloc output
Running out of memory, while usually not a problem for small programs, is a potential source for segfaults and other bugs. Thus, we should always check to see if `malloc` succeeded or not before we try to use the pointer.
While this may be true for stack (automatic) variables, it does not hold for the heap, which is where memory allocated by `malloc` lives.
While memory is returned to the system once your program terminates, if your program runs for a long time or makes many allocations without freeing, your program will hog resources and potentially slow down your system!
As a rule of thumb, there should be a `free` for every `malloc`. Note that you should free all the memory you allocated before you exit, and preferably when you are done with what you were using.
You can use tools like `valgrind` to check your programs memory usage and leakage.
There are four main memory-allocation library functions in C:
*`malloc`
*`calloc`
*`realloc`
*`free`
You've already seen `malloc`, which allocates some amount of bytes on the heap, and `free` which tells the memory allocator that it can reuse that segment.
### `calloc`: contiguous allocate
Suppose you need an array that you will read and write from (e.g. when implementing a hash map).
If you use malloc, there is a chance that you will have garbage data in your array since malloc does not set the memory it gives you.
This can be problematic if you expect the array to be empty.
This is where `calloc` comes to the rescue!
Calloc sets the memory it provides to zero and has a handy signature for when allocating arrays.
```C
// If you're doing this...
int *arr1 = malloc(sizeof(int) * 10);
if (arr)
memset(arr, 0, sizeof(int);
// ...you can do this instead!
int *arr2 = calloc(10, sizeof(int));
```
**Note:** the first approach is more flexible since you can set the "default" value to whatever you want via `memset`. `memset` is declared in `string.h`.
### `realloc`: reallocate
What happens when you need more memory for your array? Instead of manually allocating a new heap segment and copying over memory, you can use `realloc`.
`realloc` changes the size of an old allocation to the specified size.
This means you tried to access memory you do not have access to. A common pointer to dereference that you do not have access to is the `NULL` pointer (`0x0`). This is why it is important to check your pointers before you use them when you cannot guarantee validity (such as from `malloc`).
- **Leaks**
If you do not free memory in a timley fashion (or at all), you can leak memory, which can make your program (and maybe even your system) slow!
- **Logical errors**
The general pattern is allocate, use, and free. If you deviate from this pattern, you cause many problems such as a double free or the aforementioned segfault.