Allocation de mémoire
new - delete
Accueil

du site

Réservation statique - réservation dynamique

Il arrive souvent que l'on ait à réserver de la mémoire pour y enregistrer des données pouvant occuper un espace important.

C'est le cas des fichiers composés d'une suite (tableau) de structures telles que :

 typedef struct
  {
   char Nom [CAR_MAX_NOM + 1];
   char Prenom[CAR_MAX_NOM + 1];
   //...........etc.............
  } Fiche;

On est alors tenté de déclarer ce tableau sous la forme :

Fiche Fichier[NB_MAX_FICHES];

Ce qui réserve bien l'espace nécesaire en mémoire.

Si on compte y enregistrer tout de suite un nombre de fiches proche de NB_MAX_FICHES, c'est la meilleure solution.

Mais, dans les premiers temps de la saisie, peu de fiches sont rentrées et l'espace réservé est abusivement grand vis à vis de l'espace réellement utilisé.

Or la mémoire d'un ordinateur est une ressource partagée avec les autres programmes actifs.
Il faut l'économiser, sinon le fonctionnement devient très lent à cause de la gestion de mémoire virtuelle.

Ce mécanisme intervient quand la réservation de mémoire par les programmes actifs dépasse la capacité physique de la mémoire réelle.
Il enregistre provisoirement sur disque les segments de mémoire non utilisés à un moment donné par les programmes actifs et libère en mémoire physique l'espace necessaire pour la tâche en cours.
Quitte à restituer le segment enregistré lorsque la tâche en cours sera terminée.

Tous ces aller-retour entre mémoire et disque ralentissent considérablement les programmes.

Deux solutions :

  • accroître la capacité de la mémoire physique (ajouter des barettes)
  • économiser la mémoire lors de la programmation.

Pour économiser la mémoire, rien de tel que de n'utiliser à chaque moment que la quantité strictement nécessaire.

La méthoode précédente :

Fiche Fichier[NB_MAX_FICHES];

ne peut pas être très économe car si on déclare NB_MAX_FICHES = 20, on ne pourra changer ce nombre à 30 ou 40 qu'en recompilant le programme, ce que le client ne peut pas faire.

Il est heureusement possible de réserver de la mémoire progressivement, au cours du déroulement du programme, au fur et à mesure des besoins.


Attention ! cette opération est de la compétence du système d'exploitation de votre ordinateur.
Heureusement pas de la nôtre car ce n'est pas simple ...

L'OS (Operating System) ou "système d'exploitation" doit :

  • veiller à ce qu'il y ait assez de mémoire compte tenu de la taille de la variable que vous voulez réserver.
  • s'il n'y en a pas assez il faut qu'il vous le dise sans "planter" l'ordinateur.
  • l'espace mémoire est partagé entre votre application et les autres applications que vous avez lancées et qui tournent en tâche de fond : il faut savoir où tout ce monde se situe et qui possède quoi.
  • Il arrive qu'il n'y ait pas assez de mémoire physique RAM pour continuer.
    L'OS se livre alors à un exercice périlleux qui consiste à enregistrer provisoirement sur disque une partie de la mémoire non immédiatement utilisée afin de pouvoir "caser" dans la RAM des segments de mémoire pour les données demandée à ce moment. C'est ce qu'on appelle le mécanisme de mémoire virtuelle.
    Où sont vos donnés dans tout çà ?
    L'OS seul le sait !

Il vaut mieux laisser à l'OS cette gestion compliquée (d'ailleurs on ne peut pas faire autrement).

Nous disposons pour cela de deux opérateurs (ce ne sont pas des fonctions) :

  • new pour demander à l'OS de vous réserver de la mémoire (et pour vous dire où il l'a réservée)
  • delete pour libérer la mémoire précédemment réservée

Et, aussi de deux fonctions :

  • malloc()
  • free()

La suite vous montrera comment les utiliser

Pour le moment, nous commençons par "new" et "delete"
Pour les fonctions malloc() et free() voir le lien malloc&free

 

Opérateurs "new" et "delete" par des exemples

Pour réserver un entier
Déclarer un pointeur d'entier :

int *pN //Par exemple

pN = new int;

pN pointe maintenant sur une variable de type entier qui a été réservée en mémoire pas l'OS.

Pour se servir de cette variable

*pN = 3; //Par exemple

Pour libérer la mémoire de cette variable :

delete pN;


Pour réserver un caractère
Déclarer un pointeur de caractère:

char *pCar //Par exemple

pCar = new char;

pCar pointe maintenant sur une variable de type caractère qui a été réservée en mémoire pas l'OS

Pour se servir de cette variable

*pCar = 'Q'; //Par exemple, ou :
printf("%c", *pCar);
scanf("%c",pCar);

char *pc = new char( 'a' ); //Réserve et initialise un caractère

Pour libérer la mémoire de ces variables :

delete pCar;
delete pc;


Pour réserver un tableau de caractères
Déclarer un pointeur de caractère :

char *pCar //Par exemple

pCar = new char[10];

pCar pointe maintenant sur un tableau de 10 variables de type caractère qui ont été réservées en mémoire pas l'OS.

char * pC = new char['a','b','c']; //Réserve et initialise du même coup.

Pour se servir de ces tableaux

printf("%c", pCar[7]);
char u = pC[2]; // u sera 'c'

Pour libérer la mémoire de ces variables :

delete[] pC; // Vous avez bien remarqué les crochets" [] "


Pour réserver un tableau de structures

Déclarer un type de stucture :

 typedef struct
  {
   char Nom [CAR_MAX_NOM + 1];
   char Prenom[CAR_MAX_NOM + 1];
   //.................................................
  } Fiche;

Déclarer une variable de type pointeur sur cette structure :

Fiche *pF; //Par exemple

pF = new Fiche[17];

pCar pointe maintenant sur un tableau de 17 variables de type "Fiche" qui ont été réservées en mémoire pas l'OS.

Pour se servir de ce tableau

printf("Nom : %s", pF[5].Nom]); // Par exemple

Pour libérer la mémoire de ces variables :

delete[] pF; // Encore des crochets" [] "


Et maintenant quelques spécialités de C++
date *pmc = new date( 3, 12, 1985 );
//Réserve et initialise la structure ou tableau "date"
char (*pchar)[10] = new char[lignes][10];
//Tableau bi-dimensionnel : lignes par 10
//Seule " lignes " peut être une variable
int (**p) () = new (int (*[7]) ());
// Tableau de 7 pointeurs de fonctions
// ne prenant pas d'arguments
// et retournant un entier.

C++ apparaît parfois comme une langue étrangère... mais çà marche !
delete pmc;
delete pchar;
delete *p;


Les règles

Réservation d'une variable :

pointeur_de_variable = new type_de_la_variable ;
delete pointeur_de_variable ;

Réservation d'un tableau de variables :

pointeur_de_variable = new type_de_la_variable[nombre_d_elements] ;
delete[] pointeur_de_variable ;


Exemple d'application : Annuaire
Gestion par malloc( ) & free( )
Sommaire Langage C
Accueil

du site