# Lesson 11.3. Dynamic memory allocation

## Memory allocation

Suppose we want to write a program that loads a text from a file. We can't know a priori how big the text will be. This is a problem for the declaration of the string that will contain this text. The solution to this problem is dynamic allocation. If we declare a string of 999 characters, this size will be fixed at compile time and immutable. This becomes a problem if the file contains 2000 characters.

``char text;``

The solution is to declare a character pointer, then allocate the necessary memory on demand:

``````char * text;
text = malloc(1000 * sizeof(char));``````

## Malloc

`malloc()` is a function in the standard C library `stdlib.h`. malloc stands for Memory ALLOCation. This function allocates (or reserves) a block of memory of a defined size in bytes.

``````#include <stdlib.h>
void* malloc(size_t size)``````

The `malloc()` function allocates a block of memory of `size` bytes and returns the address of the beginning of the block. If `malloc()` fails to allocate the memory, the function returns a null pointer (0). Note that, as for arrays, the block of memory is necessarily continuous.

The type of the function is `void*`, which might at first seem paradoxical. In reality, it means that the function returns a pointer without any associated type. It is up to the developer to cast the pointer to the desired type:

``````// Declare an integer pointer
int * buffer;

// Allocate 200 integers for the buffer
buffer =(int*)malloc(200 * sizeof(int));``````

`buffer` can be used exactly as an array :

``buffer = 30;``

## Free

The `free` function free (deallocate) previously allocated memory.

``void free (void* ptr);``

Let's go back to the previous example, when `buffer` is not used anymore, it is possible to deallocate (free) the memory :

``````// Dynamically allocate an array of 200 integers
int * buffer;
buffer =(int*)malloc(200 * sizeof(int));

...

// Free the memory used by the array
free (buffer);``````

A classic mistake when using dynamic allocation is to allocate memory, but forget to free it. The program reserves more and more memory blocks, but does not free them (or only partially). The program ends up using all the available memory and

• at best, slows down other applications;
• at worst, crashes the machine.

Here is an example of code that should absolutely be avoided:

``````char* buffer;
while (1) {
// Allocate 10Mb
buffer = (char*)malloc(1e7);
...
// No call to free(buffer);
}``````

The above code was executed on a PC with 32GB of RAM. It takes less than a minute to crash the computer:

## Realloc

The `realloc` function modifies (increase or decrease) the size of a previously allocated block. Here is an example:

``````float tab*;
// Allocate an array of 100 floats
tab = (float*)malloc(100 * sizeof(float));

...

// Modify the array for 500 cells
tab = (float*)realloc(tab, 500 * sizeof(float));``````

Note that the `realloc()` function can change the pointer address if necessary. In this case, the original data will be copied into the new block. If the new block is larger, the excess will contain arbitrary values.

## Exercise

Write a program that

• declares an integer pointer `*ptr`
• asks the user for the size of the array
• dynamically allocates memory for the array
• checks that the allocation has been successful
• fills the array with random numbers between 0 and 20
• displays the array
• releases the memory of the array
```How many cells in array: 50
1 4 9 19 8 10 10 9 15 10 2 19 20 4 20 7 3 15 16 16 17 14 12 9 2 5 5 13 1 19 5 0 3 12 17 9 1 7 16 16 15 18 12 14 20 10 20 2 2 15
```

Test the program with ten billion cells in array :

```How many cells in array: 10000000000
Not enough memory.
exit status 1
```

## Quiz

What is the purpose of dynamic allocation?

What does the following code do?

``buffer = (int*)malloc(1000);``

What is a memory leak?

With the `realloc()` function...

What will happen to the `ptr` pointer?

``ptr = (char*)realloc(ptr, 100);``