Dynamic memory allocation in C

D

Standard memory allocation and release functions are usually declared in the stdlib.h header file.

    -void * malloc (size_t size);
    -void * calloc (size_t nmemb, size_t size);
    -void * realloc (void * ptr, size_t size);
    -void free (void * ptr);

The three allocation functions (malloc, calloc, and realloc) result in the assigned memory allocation (void *) and as a common argument the size in bytes of the allocated memory area (size_t).

If the allocation request can not be satisfied because there is no continuous block of the requested size, then the allocation functions result in NULL, which is a void * pointer to the memory address 0, which by convention is an invalid address – there is no data stored in that area.

E.g
char * str = malloc (30); // Allocate memory for 30 characters
int * a = malloc (n * sizeof (int)); // Allocate memory for. n whole numbers

The memory size taken as a malloc parameter () is specified in bytes, regardless of the type of data that will be stored in that memory region! For this reason, to allocate sufficient memory, the number of items you want to multiply should be multiplied by the size of an element when a malloc () call is made.

Memory allocation for a vector and initialization of the zoned area can be done with the calloc function.
int * a = calloc (n, sizeof (int)); // Assign memory for n integers and initialize the zone with zero
The above code is perfectly equivalent (but faster) with the following sequence of instructions:
int i;
int * a = malloc (n * sizeof (int);
for (i = 0; i <n; i ++) {
    and [i] = 0;
}

While the malloc () function takes a single parameter (a byte size), the calloc () function receives two arguments, a vector length, and a dimension of each element. Thus, this function is specialized for organized memory as a vector, while malloc () does not take into an account memory structure.

This also brings an extra measure of safety because the multiplication between the number of elements and the size of the data type could make overflow and the size of the allocated memory is not in the expected reality.

The reallocation of a vector that increases (or decreases) from the previously estimated size can be done with the realloc function, which receives the old address and the new dimension and returns the new address:
int * aux;
aux = realloc (a, 2 * n * sizeof (int)); // Doubling the previous dimension (n)
if (aux) // if aux is different from NULL
    a = aux;
else
    // Processing in case of error

In the example above, the new address is also stored in the variable pointer a, replacing the old address (which is no longer needed and not to be used anymore). The realloc () function performs the following operations:

    -presents an area of ​​the size specified as the second argument
    -copies the old address data at the new address (the first argument of the function)
    -number the memory from the old address.

If it fails to allocate memory, the realloc () function returns NULL leaving the original unchanged pointer. For this reason we check whether the reallocation succeeded and then assign the result of the pointer a.
The free () argument has an address (a pointer) argument and relieves the area from that address (allocated by calling a function such as [m | c | re] alloc). The size of the area should no longer be specified because it is remembered by the memory allocation system in some internal structures.

About the author

Ilias spiros
By Ilias spiros

Recent Posts

Archives

Categories