210 likes | 342 Views
GEF 243B Programmation informatique appliquée. Pointeurs aux fonctions, allocation dynamique de la mémoire et tableaux de pointeurs §10.4 – 10.5 , Apx I. Revue. Répondez dans quelle région de mémoire du programme sont chacune des lignes suivantes: Code, pile, données ou tas: //A program
E N D
GEF 243BProgrammation informatique appliquée Pointeurs aux fonctions, allocation dynamique de la mémoire et tableaux de pointeurs §10.4 – 10.5 , Apx I
Revue • Répondez dans quelle région de mémoire du programme sont chacune des lignes suivantes: Code, pile, données ou tas: //A program int i = 0; //où? void main (void) { int j = 0; // où? j++; // où? } int Fctn () { static int k = 0; // où? int l = 0; // où? l = l + 5; // où? } JGA Beaulieu
Synopsis • Pointeurs aux fonctions • Allocation dynamique de la mémoire • malloc() • calloc() • free() • Tableaux de pointeurs JGA Beaulieu
Pointeurs aux fonctions • Les fonctions occupent de l’espace de mémoire tout comme les autres entités de code tel que les variables, tableaux, structures… • Le nom d’une fonction est un pointeur constant similaire au nom d’un tableau • Il est donc possible d’avoir des variables pointeurs qui peuvent pointer à des fonctions • Tout comme il est possible d’avoir des variables pointeurs qui pointent aux tableaux JGA Beaulieu
Pointeurs aux fonctions • La syntaxe pour la déclaration d’un pointeur à une fonction est différente des autres types de pointeurs • On se souvient qu’une variable de pointeur est déclaré avec le type du pointeur, l’étoile * et le nom de la variable pointeur : int* pInt; //un pointeur à un int char* pChar; //un pointeur à un char JGA Beaulieu
Pointeurs aux fonctions • La syntaxe de déclaration pour un pointeur à une fonction est similaire à une déclaration de prototype • Elle commence avec le type de la fonction (ce que la fonction retourne), • Le nom de la variable pointeur à une fonction entre parenthèse (par convention on utilise fp pour commencer le nom) et, • Les types des paramètres entre parenthèses: int (*fpInts) (int, int); void (*fpConverti) (char); char* (*fpString) (char* ,char*); JGA Beaulieu
Pointeurs aux fonctions • Une des utilisations principales des pointeurs aux fonctions est de passer le nom d’une fonction (son adresse) à un gestionnaire de tâches • Le pointeur à une fonction est donc utilisé pour démarrer des tâches dans certains systèmes • Une des raisons principales pour utiliser des pointeurs aux fonctions est que le nom d’une fonction tâche peut ne pas être connu avant le temps d’exécution • La flexibilité que nous donne les pointeurs aux fonctions est donc un élément clé pour concevoir des systèmes dynamiques JGA Beaulieu
On peut passer un pointeur à une fonction comme paramètre à une autre fonction: #include <stdio.h> void ExecUnit(void (*fp) (int, int), int, int); void Difference (int a, int b); void main(void) { ExecUnit(Difference, 5,4); getchar(); } void Difference (int a, int b) { printf("Difference is: %d", a-b); return; } void ExecUnit(void (*fp) (int, int), int c, int d) { (*fp)(c,d); return; }
Allocation dynamique de la mémoire • Demander plus de mémoire… • Et l’obtenir. JGA Beaulieu
Allocation dynamique de la mémoire SVP monsieur, j’en veux plus JGA Beaulieu
Allocation dynamique de la mémoire • Nous avons vue un exemple de malloc quand nous avons appris les pointeurs à void • La fonction malloc retourne un bloc de mémoire qui contient le nombre d’octets spécifié par son paramètre. • La fonction retourne un pointeur à void pour le premier octet du bloc de mémoire nouvellement alloué • La mémoire allouée contient des déchets JGA Beaulieu
Allocation dynamique de la mémoire • Le prototype de malloc (tel que définit dans le langage) est montré ici: void* malloc (size_t size); • Le typedef size_t est définit dans plusieurs fichiers entête incluant stdio.h et mem.h • Il est habituel d’utiliser l’opérateur sizeof() quand on demande de la mémoire: int* pInt = NULL; pInt = (int *)malloc (sizeof(int)); JGA Beaulieu
Allocation dynamique de la mémoire • Un appel à malloc demande de la mémoire sur le tas. Si il n’y a pas assez de mémoire sur le tas du programme, vous avez une condition qui s’appelle débordement • C’est la responsabilité du programmeur de s’assurer qu’un débordement ne se produit pas, ou de résoudre le problème si cela se produit pInt = (int *)malloc (sizeof(int)) if (pInt == NULL) exit(1); //Pas de mémoire disponible • Si on laisse un débordement se produire sans le traiter, on peut obtenir des résultats invalides ou un crash. JGA Beaulieu
Allocation dynamique de la mémoire • calloc est une autre façon de demander de la mémoire. Cette fonction est surtout utilisée pour les tableaux. • calloc diffère de malloc de deux façons principales: • Elle alloue un bloc contiguë de mémoire capable de contenir tout le tableau. Elle demande que l’on connaisse le nombre des éléments dans le tableau et la grosseur des éléments • calloc claire toute la mémoire avec des zéros JGA Beaulieu
Allocation dynamique de la mémoire • Vous utilisez calloc comme suit: int* pInt = NULL; if (!pInt = (int*)calloc (200,sizeof(int)))) exit(1); //pas de mémoire sort • Cet appel donne de la mémoire pour un tableau de 200 éléments de type int JGA Beaulieu
Allocation dynamique de la mémoire • Vous devriez toujours relâcher la mémoire quand vous en avez plus besoin • Pour ce faire vous utilisez la fonction free pour relâcher la mémoire dynamique free(pInt);//relâche le bloc de //mémoire pointé par pInt JGA Beaulieu
Allocation dynamique de la mémoire • Quand vous utilisez la fonction free, c’est le bloc de mémoire à qui l’on pointe qui est relâché. La variable pointeur existe encore. • Le pointeur contient l’adresse du bloc de mémoire même après le free!!! • Une erreur commune est d’utiliser un pointeur à un bloc de mémoire après un free. C’est une bonne pratique que de mettre le pointeur à NULL immédiatement après un appel à free JGA Beaulieu
Tableaux de pointeurs • Une des structures les plus utiles que nous pouvons construire avec la mémoire dynamique est un tableau de pointeurs • Ce genre de structure est utile quand le nombre d’éléments varie de rangée en rangée dans le tableau. • Nous pourrions utiliser un tableau de grandeur fixe (2-D) avec la dimension maximum qui est égale à la plus grande rangée, mais cela serait une perte d’espace JGA Beaulieu
Tableaux de pointeurs • Vous déclarez un tableau de pointeurs comme suit: int** table; • Après la déclaration, vous demandez de la mémoire pour chaque rangée dans le tableau à 2-D. • La prochaine diapo provient de votre livre de C Forouzan edition 2 (p.492) JGA Beaulieu
Quiz Time • Quelle est la syntaxe pour déclarer un pointeur à une fonction? • Où est-ce que la mémoire est allouée pour les fonctions malloc et calloc? JGA Beaulieu