8PRO100
Éléments de programmation
Allocation dynamique de la mémoire
Allocation statique et dynamique
Jusqu’à maintenant, toutes la mémoire que nous avons utilisée dans nos programmes devait être allouée avantl'exécution à l’aide des déclarations de variables.
Il est parfois utile d’allouer une partie de l’espace mémoireen cours d’exécution.
Exemple 1
Par exemple si on a besoin de mémoriser un certains nombre d’objets mais que ce nombre n’est pas connu avant l’exécution du programme.
Il faut alors allouer suffisament d’espace au cas ou le nombre d’objets soit grand.
Si le nombre d’objets est petits, on gaspille inutilement de l’espace mémoire.
Le fichier d’en-tête stdlib.h
Le fichier d’entête stdlib.h contient des déclarations de fonctions traitant, entre autres, de l’allocation de la mémoire:
- malloc- free- calloc- realloc
void *malloc(size_t s)
size_t est un type d’entiers positifs.
malloc retourne un pointeur sur un espace mémoire réservé à un objet de taille s, ou bien NULL si cette demande ne peut être satisfaite. La mémoire allouée n’est pas initialisée.
Exemple 2
int *p;
*p = 10; /* INVALIDE puisque p ne pointe sur *//* aucune case mémoire valide */
p = (int) malloc(sizeof(int))
*p = 10; /* VALIDE */
p:
p:
Avant malloc
Après malloc
Exemple 2
int *p;
*p = 10; /* INVALIDE puisque p ne pointe sur *//* aucune case mémoire valide */
p = (int) malloc(sizeof(int))
*p = 10; /* VALIDE */
p:
p:
Avant malloc
Après malloc
Pourquoi?
Pointeurs sur void
La fonction malloc ne sait pas à quoi servira l’espace mémoire qui lui est demandée.
Elle ne sait pas quel type d’objet utilisera cet espace.
Alors, elle retourne un pointeur générique qui peut être converti en n’inporte quel type de pointeur: un pointeur sur void
Conversion implicite
En C, certaine conversion de type sont implicite:
double x;int n;char c;
n = c; /* un char est converti en un int */c = n; /* un int est converti en un char */x = n; /* un int est converti en un double */n = x; /* un double est converti en un int */
Conversion explicite
Dans toute expression, on peut forcer explicitementdes conversions de types grâce à un opérateur unaire appelé cast.
Dans la construction(nom de type) expression
l’expression est convertie dans le type précisé (selon certaines règles).
Exemple 3
printf(“%d”, pow(2,3)); /* mauvaise façon */
printf(“%d”, (int) pow(2,3)); /* bonne façon */
Exemple 4
int *p;struct complexe *cplx;
p = (int *) malloc(sizeof(int));
cplx = (struct complexe *) malloc(sizeof(struct complexe));
void free(void * p)
free libère l’espace mémoire pointé par p; elle ne fait rien si p vaut NULL.
p doit être un pointeur sur un espace mémoire alloué par malloc, calloc ou realloc.
void *calloc(size_t nobj, size_t s)
calloc retourne un pointeur sur un espace mémoire réservé à un tableau de nobj objets, tous de taille s, ou bien NULL si cette demande ne peut pas être satisfaite.
La mémoire allouée est initialisée par des zéros.
void *realloc(void *p, size_t s)
realloc change en s la taille de l’objet pointé par p.
Si la nouvelle taille est plus petite que l’ancienne, seul le début du contenu de l’objet est conservé.
Si la nouvelle taille est plus grande, le contenu de l’objet est conservé, et l’espace mémoire supplémentaire n’est pas initialisé.
realloc retourne un pointeur sur un nouvel espace mémoire, ou bien NULL si cette demande ne peut pas être satisfaite, auquel cas *p n’est pas modifié.
Exemple 5On veut lire des entiers et les mettre en mémoire.
Plutôt que de créer un tableau avant l’exécution, on utilisecalloc pendant l’exécution.
int *p, n;scanf(“%d”, &n);p = (int *) calloc(n, sizeof(int));
si plus tard cet espace n’est plus suffisant, alors on utilise:
p = (int *) realloc(p, 2*n);
p: …
Exemple 6Liste chaînée
struct Maillon{ int valeur; struct Maillon *suivant;};typedef struct Maillon maillon;
maillon *chaine, *p;
chaine:
p:
Exemple 6
chaine = (maillon*) malloc(sizeof(maillon));
chaine:
p:
valeur suivant
Exemple 6
chaine = (maillon*) malloc(sizeof(maillon));chaine -> valeur = 8;
chaine: 8
p:
Exemple 6
chaine -> suivant = (maillon*) malloc(sizeof(maillon));
chaine: 8
p:
Exemple 6
p = chaine -> suivant;
chaine: 8
p:
Exemple 6
p -> valeur = 5;
chaine: 8 5
p:
Exemple 6
p -> suivant = (maillon*) malloc(sizeof(maillon));
chaine: 8 5
p:
Exemple 6
p = p -> suivant;
chaine: 8 5
p:
Exemple 6
p -> valeur = 13;p -> suivant = NULL;
chaine: 8 5
p:
13 0
Exemple 6
p = chaine;while (p != NULL){ printf(“%d\n”, p->valeur); p = p->suivant;}
chaine: 8 5
p:
13 0
Exemple 6
for (p=chaine; p!=NULL; p=p->suivant) printf(“%d\n”, p->valeur);
chaine: 8 5
p:
13 0
Top Related