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[1000];
The solution is to declare a character pointer, then allocate the necessary memory on demand:
char * text;
text = malloc(1000 * sizeof(char));
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[199] = 30;
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
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:
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.
Write a program that
*ptr
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