Brefs rappels sur la pile et le tas (Stack / Heap) et les pointeurs (exemples en C) v1.11 - Olivier Carles 1
Pile et Tas Mémoire allouée de manière statique Mémoire Allouée Dynamiquement variables locales arguments valeur de retour Tas Pile v1.11 - Olivier Carles 2
Allocation statique et dynamique de la mémoirem moire char message[] = " Bonjour "; La mémoire m moire nécessaire n au stockage de message est connue à la compilation Allocation statique Que se passe-t-il pour un message non connu avant l exl exécution? Allocation dynamique : malloc(), calloc(), realloc() Libération : free() v1.11 - Olivier Carles 3
malloc() Prototype de la fonction : void * malloc(size_t num); size_t défini dans stdlib.h, généralement par unsigned int Alloue num octets pour le stockage et retourne l adresse du 1er octet Retourne NULL si échec "void*" est un type de pointeur générique g pouvant pointer sur tout type de donnée v1.11 - Olivier Carles 4
Exemple d utilisation de malloc() /* allocation pour une chaîne de 100 charactères res */ char * acharptr; acharptr = (char*) malloc(100); /* 50 entiers */ CAST int * anintarray; anintarray = (int*) malloc(50 * sizeof(int)); /* 10 réels */ float * afloatarray; afloatarray = (float*) malloc(10 * sizeof(float)); v1.11 - Olivier Carles 5
Conversion de type pointeur (CAST) Pourquoi (char *), (int( *), and (float *)? nième élem 2ème élem Tableau De combien d octets faut-il se déplacer en mémoire pour passer d un élément au suivant? Le type du pointeur donne ce nombre : c est la taille en octets du type T de (T*)malloc( ) 1er élem v1.11 - Olivier Carles 6
sizeof() Attention : la taille des entiers et réels est dépendante des systèmes mes. D où : utiliser sizeof() pour connaître la taille d un type. sizeof() fonctionne aussi pour les structures utilisateur aussi complexes soient- elles : malloc(n * sizeof(astructname astructname)) malloc(n * sizeof(avariablename avariablename)) v1.11 - Olivier Carles 7
Exemple : la liste chaînée e! /* liste.h */ struct Cell int valeur; struct Cell * suiv; }; typedef struct Cell Cell; Cell * ConstruitListe(int taille); void AfficheValeursCellules(Cell * tete); void LibereCellules(Cell * tete); v1.11 - Olivier Carles 8
La liste chaînée #include <stdlib.h< stdlib.h> #include <malloc.h< malloc.h> #include <stdio.h< stdio.h> #include "liste.h" liste.h" int main(void) Cell * tete; tete = ConstruitListe(10); /* BP1 Cf mémoiremoire sur transp. suivant */ AfficheValeursCellules(tete); DetruitListe(tete); } return 1; v1.11 - Olivier Carles 9
La liste chaînée Cell * ConstruitListe(int taille) int i; Cell * cour,, * tete; } tete = NULL; for(i = 1; i <= taille; ; i++) cour = (Cell *) malloc(sizeof(cell)); ); cour->valeur = i; cour->suiv = tete; /* BP2 Cf + loin */ tete = cour; } return tete; v1.11 - Olivier Carles 10
La liste chaînée void AfficheValeursCellules(Cell * tete) } Cell * cour = tete; while(cour) } printf("%d\n", ", cour->valeur valeur); cour = cour->suiv suiv; v1.11 - Olivier Carles 11
La liste chaînée void DetruitListe(Cell * tete) Cell * temp; while(tete) temp = tete; tete = temp->suiv suiv; free(temp); } } v1.11 - Olivier Carles 12
En mémoire, m moire, au point d arrêt d BP1 tete suiv suiv Pour main() valeur 10 valeur 9... suiv suiv valeur 2 valeur 1 Pile Tas v1.11 - Olivier Carles 13
En mémoire, m moire, au point d arrêt d BP2 tete cour suiv i taille (param. Fct ) 2 10 valeur 1 Pour ConstruitListe() tete? Pour main() suiv valeur 2 Pile Tas v1.11 - Olivier Carles 14
calloc() (Cf. malloc()) void * calloc(size_t num, size_t size); Alloue un bloc (tableau) mémoiremoire pour num éléments de taille size octets chacun Exemple : /* allocation pour un tableau de 5 éléments de type Cell */ Cell * acellptr; acellptr = (Cell*) calloc(5, sizeof(cell)); v1.11 - Olivier Carles 15
free() La mémoire m moire disponible pour le tas est évidemment de taille finie donc il faut libérer les blocs mémoiresm moires alloués quand ils ne sont plus utilisés void free(void * ptr); Sans effet si ptr == NULL NB : pas de taille en octets à indiquer v1.11 - Olivier Carles 16
realloc() void * realloc(void * memblock,, size_t size); Change la taille d un bloc mémoiremoire indiqué par memblock en un bloc de size octets Plusieurs cas : realloc() se passe bien : retourne l adresse du bloc realloué (éventuellement returne memblock si une simple extension du bloc a été possible). Si memblock == NULL, équivalent à malloc() Si size == 0, équivalent à free(), retourne NULL Si pas assez de mémoire, retourne NULL v1.11 - Olivier Carles 17
En règle r généraleg Ne jamais supposer qu une une opération d allocation d dynamique de mémoire m moire s est bien dérould roulée Donc toujours tester les valeurs retournées es par les fonctions #include <stdlib.h> #include <malloc.h> #include <stdio.h> int main() char * string; string = malloc(10000); if( string == NULL ) /* if (!string) */ printf( ( "Not" enough memory!\n" ); else printf( ( "Memory space allocated\n" ); free( string ); printf( ( "Memory freed\n" ); } return 0; } v1.11 - Olivier Carles 18