Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Industrial programming >> Langue C

Allocation mémoire dynamique en C : Maîtriser malloc, calloc, realloc et free

Avant de plonger dans l'allocation mémoire dynamique en C, il est essentiel de comprendre comment la mémoire est gérée dans le langage.

Comment fonctionne la gestion de la mémoire en C

Quand vous déclarez une variable avec un type primitif, le compilateur alloue automatiquement de l'espace pour elle sur la pile (stack). Par exemple, un float occupe typiquement 4 octets (dépendant de la plateforme). Vous pouvez confirmer cela avec l'opérateur sizeof :

#include <stdio.h>
int main() {
    float x;
    printf("The size of float is %d bytes", sizeof(x));
    return 0;
}

La sortie sera :

The size of float is 4 bytes

Un tableau de taille spécifiée est aussi alloué contiguement sur la pile, chaque élément occupant la taille de son type :

#include <stdio.h>
int main() {
    float arr[10];
    printf("The size of the float array with 10 elements is %d", sizeof(arr));
    return 0;
}

Le résultat est :

The size of the float array with 10 elements is 40

Bien que l'allocation sur pile soit automatique, de nombreux programmes nécessitent de la mémoire dont la taille n'est pas connue avant l'exécution. Ce besoin est adressé par l'allocation mémoire dynamique, qui utilise le tas (heap) au lieu de la pile.

Allocation mémoire dynamique en C

L'allocation dynamique implique de demander et libérer manuellement la mémoire selon les besoins, avec des pointeurs suivant les blocs alloués sur le tas. La bibliothèque standard C fournit plusieurs fonctions pour cela :

Explorons chaque fonction en détail.

Fonction malloc()

La fonction malloc() signifie « memory allocation ». Elle réserve un bloc de mémoire de taille spécifiée et retourne un pointeur vers celui-ci. Le pointeur est généralement casté vers le type désiré :

ptr = (type_cast *) malloc(taille_octets);

Exemple :

#include <stdlib.h>
int main(){
    int *ptr;
    ptr = malloc(15 * sizeof(*ptr)); /* 15 entiers */
    if (ptr != NULL) {
        *(ptr + 5) = 480; /* sixième élément */
        printf("Value of the 6th integer is %d", *(ptr + 5));
    }
}

Sortie :

Value of the 6th integer is 480

Points clés :

  1. Utilisez sizeof(*ptr) pour rendre le code robuste contre les changements de type.
  2. Vérifiez une valeur de retour NULL pour détecter l'échec d'allocation.
  3. La mémoire allouée est contiguë ; traitez-la comme un tableau et utilisez l'arithmétique de pointeurs.

L'allocation dynamique n'est pas limitée aux types primitifs ; elle fonctionne avec les structures, tableaux de caractères, et plus.

Fonction free()

La mémoire allouée avec malloc(), calloc() ou realloc() doit être libérée explicitement pour éviter les fuites. La fonction free() effectue cette tâche :

#include <stdio.h>
int main() {
    int* ptr = malloc(10 * sizeof(*ptr));
    if (ptr != NULL){
        *(ptr + 2) = 50;
        printf("Value of the 2nd integer is %d", *(ptr + 2));
    }
    free(ptr);
}

Sortie :

Value of the 2nd integer is 50

Fonction calloc()

calloc() alloue plusieurs blocs de taille égale et initialise chaque octet à zéro, le rendant idéal pour les tableaux et structures nécessitant une mémoire initialisée à zéro :

ptr = (type_cast *) calloc(n, taille);

Exemple – sommer une suite arithmétique :

#include <stdio.h>
int main() {
    int i, *ptr, sum = 0;
    ptr = calloc(10, sizeof(int));
    if (ptr == NULL) {
        printf("Error! memory not allocated.");
        exit(0);
    }
    for (i = 0; i < 10; ++i) {
        *(ptr + i) = i;
        sum += *(ptr + i);
    }
    printf("Sum = %d", sum);
    free(ptr);
    return 0;
}

Résultat :

Sum = 45

calloc() vs malloc()

Différences clés :

Fonction realloc()

La fonction realloc() change la taille d'une allocation existante tout en préservant son contenu :

ptr = realloc(ptr, nouvelle_taille);

Exemple – étendre un tampon de chaîne :

#include <stdio.h>
int main () {
    char *ptr = malloc(10);
    strcpy(ptr, "Programming");
    ptr = realloc(ptr, 20); // agrandir
    strcat(ptr, " In 'C'");
    printf("%s, Address = %u", ptr, ptr);
    free(ptr);
    return 0;
}

Si la réallocation échoue, realloc() retourne NULL et le bloc original reste valide.

Tableaux dynamiques

Les tableaux dynamiques permettent au nombre d'éléments de croître pendant l'exécution, un motif courant dans les algorithmes et structures de données :

#include <stdio.h>
int main() {
    int *arr_dynamic = NULL;
    int elements = 2, i;
    arr_dynamic = calloc(elements, sizeof(int));
    for (i = 0; i < elements; i++)
        arr_dynamic[i] = i;
    for (i = 0; i < elements; i++)
        printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);
    elements = 4;
    arr_dynamic = realloc(arr_dynamic, elements * sizeof(int));
    printf("After realloc\n");
    for (i = 2; i < elements; i++)
        arr_dynamic[i] = i;
    for (i = 0; i < elements; i++)
        printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);
    free(arr_dynamic);
}

Résultat :

arr_dynamic[0]=0
arr_dynamic[1]=1
After realloc
arr_dynamic[0]=0
arr_dynamic[1]=1
arr_dynamic[2]=2
arr_dynamic[3]=3

Résumé

Langue C

  1. Comprendre ROM, PROM, EPROM et EEPROM : conception, programmation et identification
  2. Fondamentaux C# : Entrées et sorties essentielles
  3. Maîtriser les directives using C# : Imports, alias et directives static
  4. Maîtriser la gestion de mémoire en C++ : Utilisation experte de new et delete
  5. Quatre modèles éprouvés pour les fonctions définies par l'utilisateur en C
  6. Allocation dynamique de mémoire en C : Maîtriser malloc, calloc, realloc et free
  7. Maîtriser les fonctions de la bibliothèque standard C : Guide pratique
  8. Maîtriser l'allocation de tableaux dynamiques en C++ : Guide pratique avec exemples de code
  9. Les Fonctions en C++ Expliquées avec des Exemples de Code Pratiques