Notions de pointeurs en C

Slides:



Advertisements
Présentations similaires
C.
Advertisements

FLSI602 Génie Informatique et Réseaux
8PRO100 Éléments de programmation Allocation dynamique de la mémoire.
Les pointeurs Modes d’adressage de variables. Définition d’un pointeur. Opérateurs de base. Opérations élémentaires. Pointeurs et tableaux. Pointeurs et.
Plan cours La notion de pointeur et d’adresse mémoire.
L’essentiel du langage C
2.1 - Historique Chapitre 2 : Introduction au langage C++
Le langage C Rappel Pointeurs & Allocation de mémoire.
Notions de pointeurs en C
PRO-1027 Programmation Scientifique en C
C++ Les fonctions. Présentation Utilité : Dès qu'un programme dépasse la centaine de lignes de code, il est pratique de pouvoir le décomposer en plusieurs.
CINI – Li115 1 Semaine 9 Algorithmes de tri ● Introduction ● Tri à bulle ● - principe ● - algorithme ● - efficacité ● Tri par sélection ● - principe, algorithme,
1/1/ Synthèse TD 3 Classe et adresse IP Bertrand Chesneau Morgan Nouet.
Tableaux et Pointeurs Chaînes de Caractères Programmation Impérative II.
1- Introduction 1ère partie Le langage SQL 2- Connexion 3- Structure & Contenu 4- Requêtes.
CINI – Li115 1 Semaine 10 Les pointeurs ● Notion d'adresse ● Déclaration et utilisation de pointeurs ● "Types pointeur" et initialisation des pointeurs.
1 Programmation en C++ Fonctions ● Déclaration et définition de fonctions ● Arguments ● Surcharge ● Arguments optionnels ● Fonctions constantes ● Fonctions.
1 Programmation en C++ C++ de base ● Programme C++ ● Variables, objets, types ● Fonctions ● Namespace ● Tests ● Boucles ● Pointeurs, références.
1 © Copyright 2005, Philippe Arlotto tln.fr Creative Commons Attribution-ShareAlike 2.0 license 27/09/2016 Algorithmique & Langage.
1 Programmation en C++ C++ de base ● Programme C++ ● Variables, objets, types ● Types et opérations fondamentales ● Tests ● Boucles ● Pointeurs, références.
Tableaux en C Mardi 2/05.
Semaine 8 Retour sur les tableaux : fonctions et récursivité
Synthèse TP 2 Codeblock 1 Les objectifs de ce tp sont :
Les tableaux différencier les variables simples des variables indicées (ordonnées et numérotées) un identificateur unique désigne un ensemble, une collection.
Les Instructions Itératives (Les Boucles)
Introduction au Langage Pascal
Langage C Structure d'un programme Types Lire Ecrire Tester
Quelques Termes INFORMATIQUE ? ORDINATEUR ( Système Informatique)?
Chapitre 1 nombres, chaînes de caractères, booléens, et VARIABLES
Pas de variable globale
Les notions de classe et d'objet
Eléments d’Informatique Cours11 – Allocation dynamique, listes chaînées Catherine Recanati.
Allocation dynamique de mémoire
Pointeurs et langage C.
Opérateurs Toute donnée informatique est stockée en mémoire sous la forme d'une combinaison de bits (mot machine). Les opérateurs bits permettent de modifier.
Semaine #1 INF130 par Frédérick Henri.
Représentation de l’information en binaire:
AO (Architecture des ordinateurs)
Principes de programmation (suite)
Algorithmique Langage C
Séances de soutien Projet informatique 2A
Semaine 11 Les pointeurs (suite)
Les fonctions.
Matrices, déclaration en CSharp
Programmation en C++ Fonctions
SIF-1053 Architecture de ordinateurs
Arguments de la ligne de commande
Tableaux à plusieurs dimensions en langage C
Les chaînes de caractères et le langage C
IFT1969 Programmation scientifique en C Michel Reid.
6. Les types utilisateurs et les structures de données
L ES I NSTRUCTIONS I TÉRATIVES (L ES B OUCLES ) Réalisé par : OUZEGGANE Redouane Département de Technologie Faculté de Technologie – Université A.Mira,
Programmation en C++ Fonctions
Cours N°9: Algorithmiques Les Tableaux 1
Les tableaux.
Cours 8 5. Appels de fonctions Le matériel Concepts de pile
Le système binaire Table des matières : -Présentation du binaire
Programmation en C++ C++ de base
Calcul Scientifique Initiation à SCILB
Eléments de base du langage C
Les classes et les objets
Les structures de base Listes chainées. Listes Les listes(similaire aux tableaux) sont des structures informatiques qui permettent de garder en mémoire.
Cours Programmation en C. Traitement de l’information Catégorie d’information Les données Les résultats Les informations intermédiaires.
PROGRAMMATION ET ENSEIGNEMENT
Principes de programmation (suite)
QCM Pointeurs 2 / Q1 On considère la déclaration suivante : char *ptc ; ptc peut contenir : 1) des valeurs de variables de type caractère 2) des adresses.
Chapitre 2 : Représentation de l’information dans la machine Introduction Représentation des nombres négatifs –Signe / valeur absolue –Complément à 1 –Complément.
Listes Chaînées.
Python Nicolas THIBAULT
Eléments de base du langage C
Transcription de la présentation:

Notions de pointeurs en C PRO-1027 Programmation Scientifique en C Notions de pointeurs en C Sujets Notions de base sur les pointeurs Pointeurs et Tableaux (matrices) Arithmétiques sur les pointeurs Chaînes de caractères Tableaux à deux dimensions Tableaux de pointeurs Allocation de mémoire Références: http://www.cplusplus.com/doc/tutorial/pointers.html http://www.cs.cf.ac.uk/Dave/C/node10.html http://pweb.netcom.com/~tjensen/ptr/pointers.htm http://www.commentcamarche.net/c/cpoint.php3 http://www.iu.hio.no/~mark/CTutorial/CTutorial.html

Notions de base des pointeurs Si nous voulons permuter le contenu de deux variables entières x et y, nous permuterons ces variable à l’aide d’une fonction "swap(x,y)" qui permet la permutation des variables x et y (les paramètres). La version suivante de cette fonction ne fonctionne pas car même si on modifie x et y, les nouvelles valeurs permutées ne sont pas retransmises à la fin de la fonction: void swap(int x, int y) { int temp; temp=x; x=y; y=temp; }

Notions de base des pointeurs Version fonctionnelle: void swap(int *px, int *py) { int temp; temp=*px; *px=*py; *py=temp; } Appel à la procédure swap(): int x=3, y=5; swap(&x,&y); // &x: & retourne l'adresse de la variable x // x=5 et y=3 au retour du swaP()

Notions de base des pointeurs La plupart des langages de programmation offrent la possibilité d'accéder aux données dans la mémoire de l'ordinateur à l'aide de pointeurs, Un pointeur est une variable affectée à la valeur d’un adresse. En C, les pointeurs jouent un rôle primordial dans la définition de fonctions Sachant que le passage des paramètres en C se fait toujours par valeur, Les pointeurs permettent de passer une référence sur un objet à une fonction appelée. Le pointeur permet donc de changer le contenu de variables déclarées dans d'autres fonctions. Ainsi le traitement de tableaux et de chaînes de caractères dans des fonctions serait impossible sans l'utilisation de pointeurs.

Notions de base des pointeurs Modes d’adressage Adressage direct : Dans la programmation, nous utilisons des variables pour stocker des informations. La valeur d'une variable se trouve à un endroit spécifique dans la mémoire interne (RAM) de l'ordinateur. Le nom de la variable nous permet alors d'accéder directement à cette valeur. Donc l’adressage direct permet l’accès au contenu d'une variable par le nom de la variable. Adressage indirect : Accès au contenu d'une variable, en passant par un pointeur qui contient l'adresse de la variable. Donc l’accès à une valeur d’une variable se fait par l’accès préalable au contenu d’un pointeur.

Notions de base des pointeurs Un pointeur est une variable qui contient l'adresse d'une autre variable. En langage C, chaque pointeur est limité à un type de données. Il peut contenir l'adresse d'une variable simple de ce type ou l'adresse d'une composante d'un tableau de ce type. Si un pointeur P contient l'adresse d'une variable A, on dit que 'P pointe sur A'. Un pointeur est une variable qui peut 'pointer' sur différentes adresses. Le pointeur pouvant être affecté à différentes adresses. Le nom d'une variable reste quant à lui toujours lié à la même adresse en RAM.

Notions de base des pointeurs Opérateurs sur les pointeurs &<var>: opérateur unaire qui retourne l’adresse de la variable var. int N; printf("Entrez un nombre entier : "); scanf("%d", &N); // scanf() prend une adresse comme deuxieme argument *<p>: opérateur unaire qui retourne le contenu pointer par p un pointeur. int A=10, B; int *P; P = &A; B = *P; *P = 20; A 10 A 20 3 B 10 2 1 P &A 1 2 3

Notions de base des pointeurs Déclaration des pointeurs <Type> *<NomPointeur> : déclare un pointeur <NomPointeur> qui être affecté des adresses de variables du type <Type> Une déclaration comme: int *P ; Le pointeur P est du type int *, donc P est un pointeur sur des objets int P contient donc l'adresse d‘objet de type int Lors de la déclaration d'un pointeur en C, ce pointeur est lié explicitement à un type de données. Donc la variable pointeur P déclarée comme pointeur sur des int ne peut pas recevoir l'adresse d'une variable d'un autre type que int.

Notions de base des pointeurs Opérations sur les pointeurs Les opérateurs * et & ont la même priorité que les autres opérateurs unaires (la négation !, l'incrémentation ++, la décrémentation --). Dans une même expression, les opérateurs unaires *, &, !, ++, -- sont évalués de droite à gauche. Si un pointeur P pointe sur une variable X, alors *P peut être utilisé partout où on peut écrire explicitement X. Si nous avons: P = &X; Y = X+1; // Y = *P + 1; X = X+10; // *P = *P + 10; X += 2; // *P +=2; ++X; // ++(*P); ou ++*P; X++; // (*P)++

Notions de base des pointeurs Valeur initiales La valeur numérique 0 (zéro, NULL) est utilisée pour indiquer qu'un pointeur ne pointe 'nulle part‘, sur rien. int *P ; P = 0 ; Les pointeurs sont aussi des variables et peuvent être utilisés comme telles. Soit P1 et P2 deux pointeurs sur des int, alors l'affectation P1 = P2; copie le contenu de P2 vers P1. P1 pointe alors sur le même objet que P2. Après les instructions suivantes : int A=20, B; // variable int . &A adresse de A int *P ; // P est un pointeur sur des int P = &A ; B = *P; // Contenu de A affecte a B

Notions de base des pointeurs Exercise main() { int A = 1, B = 2, C = 3; int *P1, *P2; P1=&A; // P1 pointe sur A P2=&C; // P2 pointe sur C *P1=(*P2)++; // A = 3 C = 4 P1=P2; // P1 pointe sur C P2=&B; // P2 pointe sur B *P1-=*P2; // C = 2 ++*P2; // B = 3 *P1*=*P2; // C = 6 A=++*P2**P1; // A = 24 P1=&A; // P1 pointe sur A *P2=*P1/=*P2; // B = 6 return 0; }

Pointeurs et tableaux int tableau[100]; &tableau[0] et tableau sont une seule et même adresse. Donc le nom d'un tableau est un pointeur constant sur le premier élément du tableau. int A[10], B; int *P ; P = A ; // P pointe sur A[0], P = &A[0]; equivalent B = *(P+1); // P+1 pointe sur le contenu de A[1] B = *(P+2); // P+2 pointe sur le contenu de A[2] ... B= *(P+i); // P+i pointe sur le contenu de A[i]

Pointeurs et tableaux ………………… float A[20]; float X ; float *P ; P = A ; // P pointe sur l’element A[0] X = *(P+9) ; // P+9 pointe sur l’element A[9] A représente l'adresse de l’élément A[0], *(A+1) pointe sur le contenu de A[1] *(A+2) pointe sur le contenu de A[2] ... *(A+i) pointe sur le contenu de A[i] ………………… A[0] *(A) A[19] *(A+19)

Pointeurs et tableaux Il existe une différence fondamentale entre une variable pointeur et le nom d'un tableau : Un pointeur est une variable, sa valeur peut alors changée, des opérations arithmétiques sur ces pointeurs peuvent être effectuées, comme l’affectation P = A ou des incréments P++ ou toutes autres opérations arithmétiques. Le nom associé à un tableau est une constante, donc des opérations arithmétiques comme A = P ou A++ sont illégales.

Exemple tableau VS pointeur Pointeurs et tableaux Exemple tableau VS pointeur main() { int T[10] = {-3, 4, 0, -7, 3, 8, 0, -1, 4, -9}; int POS[10]; // int * Tptr, *Pptr; int I,J; /* indices courants dans T et POS */ // Tptr = T; Pptr = POS; for (J=0,I=0; I<10; I++) if (T[I]>0) // (*(Tptr+I) > 0) POS[J] = T[I]; // *(Pptr+J) = *(Tptr+I) J++; } return 0;

Arithmétiques sur les pointeurs Affectation d’un pointeur Soient P1 et P2 deux pointeurs sur le même type de données, alors l'instruction P1 = P2 ; fait pointer P1 sur le même objet que P2. Addition et soustraction d’une valeur entière Si le pointeur P pointe sur l'élément A[i] d'un tableau, alors P+n pointe sur A[i+n] et P-n pointe sur A[i-n]. n correspond au nombre d’emplacements du type de donnée pointé qu’il faut se déplacer à partir de P pour atteindre l’emplacement recherché (P+n). Ce déplacement (décalage) correspond à un saut de n*sizeof(type de donnée) octets dans la mémoire RAM. Si P pointe sur des objets float, P+4 pointe alors sur le cinquième élément de type float, donc 16 octets à partir du début du vecteur de float pointé par P.

Arithmétiques sur les pointeurs Incrément/Décrément d’un pointeur Si P pointe sur l'élément A[i] d'un tableau, alors après l'instruction : P = &A[i]; P++ ; // P pointe sur A[i+1] P+= n ; // P pointe sur A[i+n] P-- ; // P pointe sur A[i-1] P-= n ; // P pointe sur A[i-n]

Arithmétiques sur les pointeurs Rappels importants: L'addition, la soustraction, l'incrémentation et la décrémentation sur les pointeurs sont seulement définies à l'intérieur d'un tableau. Si l'adresse formée par le pointeur et l'indice sort du domaine du tableau, alors le résultat n'est pas défini et peut causer des erreurs d’accès mémoire difficiles à détecter. Ces opérations arithmétiques sont valables également pour les pointeurs qui pointent vers des variables indépendantes, i.e., ne faisant pas partie d’un tableau. À titre d’exemple, si P pointe sur un élément de type quelconque, alors P+1 pointe sur l’octet qui suit immédiatement cet élément. Exemple : si P pointe sur un short int alors P+1 sera égale à l’adresse référencée par P plus 2 (puisque la taille d’un short int est 2 octets).

Arithmétiques sur les pointeurs Exemples d’utilisations d’opérations arithmétiques int A[10] ; int *P ; P = A+9 ; // P pointe sur le dixieme element de A P = A+11 ; // P pointe au-dela du vecteur A de 8 octets P = A-1 ; // P pointe 4 octets avant le debut de A

Arithmétiques sur les pointeurs Comparaisons de pointeurs (opérateurs relationnels) On peut comparer deux pointeurs par <, >, <=, >=, ==, !=. La comparaison de deux pointeurs qui pointent dans le même tableau est équivalente à la comparaison des indices correspondants. (Si les pointeurs ne pointent pas dans le même tableau, alors le résultat est donné par leurs positions relatives dans la mémoire).

Arithmétiques sur les pointeurs Autre exemple int A[] = {12, 23, 34, 45, 56, 67, 78, 89, 90}; int *P, *P2, B; P = A; B = *P+2; // B = 14 = A[0] + 2 B = *(P+2) + 2; // B = 36 = A[2] + 2 P2 = P+1; // P2 pointe sur A[1] P2 = &A[4]-3; // P2 pointe sur A[1] P2 = A+3 ; // P2 pointe sur A[3] B = &A[7]-P; // B = 28 P2 = P+(*P-10) ; // P2 pointe sur A[2] B = *(P+*(P+8)-A[7]); // B = 23;

Pointeurs (chaînes de caractères) Initialisation de pointeur sur des chaînes de caractères Une chaîne de caractères est stockée dans un tableau linéaire de "char". La chaîne de caractères est complétée par le caractère NULL, le zéro binaire ('\0'). char x[]="abcd"; // x est un tableau de 5 caractères, // x[4]=='\0' et aussi x[4]==0 Un pointeur de char peut être initialisé lors de sa déclaration si on lui affecte l'adresse d'une chaîne de caractères constante : char *B = "PRO1027" ;

Pointeurs (chaînes de caractères) Initialisation de pointeur sur des chaînes de caractères Il existe une différence importante entre les deux déclarations : char A[] = "PRO1027"; /* un tableau */ char *B = "PRO1027"; /* un pointeur */ A est un tableau qui a exactement la grandeur pour contenir la chaîne de caractères et le caractère de fin '\0'. Les caractères de la chaîne peuvent être changés, mais le nom A va toujours pointer sur la même adresse en mémoire. B est un pointeur qui pointe sur une chaîne de caractères constante stockée quelque part en mémoire. Le pointeur peut être modifié et pointer sur autre chose. La chaîne constante peut être lue, copiée ou affichée, mais pas modifiée.

Pointeurs (chaînes de caractères) Initialisation de pointeur sur des chaînes de caractères char *A = "Chaîne courte" ; char *B = "Chaîne plus longue"; A = B; // A pointe sur la meme chaine que B Les tableaux de caractères permettront de déclarer des chaînes de caractères que nous voulons modifier. Les pointeurs de char seront utilisés pour manipuler des chaînes de caractères constantes (dont le contenu ne change pas).

Tableaux à deux dimensions Un tableau M à deux dimensions peut être définis: int M[4][10] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, {10,11,12,13,14,15,16,17,18,19}, {20,21,22,23,24,25,26,27,28,29}, {30,31,32,33,34,35,36,37,38,39} }; Le nom du tableau M représente l'adresse du premier élément du tableau et pointe sur le tableau M[0] qui a la valeur {0,1,2,3,4,5,6,7,8,9}. M[0] pointe sur la rangée 0. L'expression (M+1) est l'adresse du deuxième élément du tableau M et pointe sur M[1] qui a la valeur {10,11,12,13,14,15,16,17,18,19}. M[1] pointe sur la rangée 1. L'arithmétique des pointeurs qui respecte automatiquement les dimensions des éléments conclut logiquement que M+i désigne l'adresse du tableau M[i].

Tableaux à deux dimensions Exemple pointeur VS tableau 2D int M[4][10] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, {10,11,12,13,14,15,16,17,18,19}, {20,21,22,23,24,25,26,27,28,29}, {30,31,32,33,34,35,36,37,38,39}}; int *P, B; P = (int *)M; /* conversion forcée */ B = *(P+(2*10) + 2); // B = M[2][2] Sachant que M est stockée ligne par ligne, il est maintenant possible traiter M à l'aide du pointeur P comme un tableau unidimensionnel de dimension 4*10.

Tableaux à deux dimensions Exemple pointeur VS tableau 2D ( des éléments de M) int M[4][10] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, {10,11,12,13,14,15,16,17,18,19}, {20,21,22,23,24,25,26,27,28,29}, {30,31,32,33,34,35,36,37,38,39}}; int *P, som=0; P = (int *)M; for(int i=0;i<4;i++) for(int j=0;j<10;j++) som += M[i][j]; // P[i*10+j] ou *(P+(i*10)+j)

Tableaux à deux dimensions Pour référencer un tableau 2D à l'aide de pointeurs, nous avons besoin de quatre données : L'adresse du premier élément du tableau converti dans le type correspondant aux éléments du tableau La longueur d'une ligne réservée en mémoire Le nombre d'éléments effectivement utilisés dans une ligne Le nombre de lignes effectivement utilisées

Tableaux de pointeurs Déclaration: <Type> *<NomTableau>[<N>] déclare un tableau <NomTableau> de <N> pointeurs sur des données de type <Type>. double *A[10]; déclare un tableau de 10 pointeurs sur des objets de type double dont les adresses et les valeurs ne sont pas encore définies. Les tableaux de pointeurs sont souvent utilisés pour mémoriser de façon économique des chaînes de caractères de différentes longueurs. Ex: Le tableaux char *argv[] passé en argument à la fonction main() d’un programme C.

Tableaux de pointeurs Nous pouvons initialiser les pointeurs d'un tableau sur char par les adresses de chaînes de caractères constantes. char *MOIS[] = {"janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"}; déclare un tableau MOIS[] de 12 pointeurs de char. Chacun des pointeurs est initialisé avec l'adresse de l'une des 12 chaînes de caractères. On peut afficher ces 12 chaînes de caractères en fournissant les adresses contenues dans le tableau MOIS aux fonction d’affichage printf() ou puts() : int i; for (i=0; i<12; i++) printf("%s\n", MOIS[i]) ; // puts(MOIS[i])

Tableaux de pointeurs Comme MOIS[i] est un pointeur de char, on peut afficher les premières lettres des mois en utilisant l'opérateur * 'contenu de' : int i; for (i=0; i<12; i++) printf("%c\n", *MOIS[i]); L'expression MOIS[i]+j correspond à la jième lettre de la iième chaîne. for (i=0; i<12; i++) printf("%c\n",*(MOIS[i]+2));

Tableaux de pointeurs Formatage des sorties avec printf()

Tableaux de pointeurs Formatage des sorties avec printf()

Tableaux de pointeurs Formatage des sorties avec printf()

Allocation dynamique Lorsque nous ne connaissons pas d’avance la dimension des tableaux que nous devons utiliser dans notre application, Nous devons trouver des moyens pour réserver et libérer de la mémoire au fur et à mesure que nous en avons besoin. Nous parlons alors de l'allocation dynamique de la mémoire. Déclaration statique de données Chaque variable dans un programme utilise un certain nombre d'octets en mémoire. Les exemples présentés utilisaient un mode de réservation de mémoire automatique appliquée lors des déclarations des données. Dans tous ces cas, le nombre d'octets à réserver était déjà connu pendant la compilation. Ce qui correspond à la déclaration statique des variables. float A, B, C; // 3 X 4 octets short D[10][20]; // 10 X 20 X 2 octets char E[] = {"PRO1027"}; // 8 octets char F[][10] = {"un", "deux", "trois", "quatre"}; // 4 X 10 octets

Allocation dynamique Déclaration de pointeurs double *G ; // machine 32 bits, 4 octets char *H ; // machine 32 bits, 4 octets float *I[10] ; // machine 32 bits, 10 X 4 octets La fonction malloc() de la bibliothèque <stdlib.h> nous aide à localiser et à réserver de la mémoire au cours d'un programme. malloc( <N> ) : retourne l'adresse d'un bloc en mémoire de <N> octets libres ou la valeur zéro s'il n'y a pas assez de mémoire. Supposons que nous avons besoin d'un bloc de mémoire pour une image de niveaux de gris (0..255) de 1024X1024 unsigned char. unsigned char *img; img = malloc(1024*1024) ; // retourne un bloc de 1024X1024 octets Si nous voulons réserver de la mémoire pour des données d'un type dont la grandeur varie d'une machine à l'autre, nous avons besoin de la grandeur effective d'une donnée de ce type. L'opérateur sizeof() nous aide alors à préserver la portabilité du programme.

Allocation dynamique sizeof <var> fournit la grandeur de la variable <var> sizeof <const> fournit la grandeur de la constante <const> sizeof (<type>) fournit la grandeur pour un objet du type <type> Exemples: short A[10]; char B[5][10]; printf(“\n valeur retourne = %d”,sizeof(A); // 10 X 2 printf(“\n valeur retourne = %d”,sizeof(B); // 5 X 10 X 1 printf(“\n valeur retourne = %d”,sizeof(“PRO1027" ); // 8 printf(“\n valeur retourne = %d”,sizeof(float ); // 4 printf(“\n valeur retourne = %d”,sizeof(double ); // 8

Allocation dynamique Libération de la mémoire Quand un bloc de mémoire que nous avons réservé à l'aide de malloc() n’est plus utilisé, nous pouvons alors le libérer à l'aide de la fonction free() de la bibliothèque <stdlib.h>. free( <Pointeur> ) Cette fonction libère le bloc de mémoire désigné par le pointeur <Pointeur>. La fonction free() peut aboutir à un désastre si on essaie de libérer de la mémoire qui n'a pas été allouée par malloc(). La fonction free() ne change pas la valeur (adresse) du pointeur; il est donc conseillé d'affecter la valeur zéro au pointeur immédiatement après avoir libéré le bloc de mémoire qui y était attaché. Si nous ne libérons pas explicitement la mémoire à l'aide de la fonction free(), alors elle est libérée automatiquement à la fin du programme. MAIS entre temps, un programme qui ne libère pas sa mémoire inutilisée peut occasionner des fuites de mémoire (memory leaks).