Vous êtes sur la page 1sur 34

L'ALLOCATION DYNAMIQUE

Brahimi Mohamed
L'allocation statique
int nombre;

Le programme demande au système d'exploitation


la réservation d'un 4 octets pour la variable nombre.

le système d'exploitation répond à votre programme en lui


Gestionindiquant
Automatique (Statique
l'adresse qu'il luipara réservée.
le compilateur)

lorsque la fonction est terminée, la variable est


automatiquement supprimée de la mémoire.
La taille d'une variable
sizeof(type)
char : 1 octets
int : 4 octets
Le nombre d'octets réservés pour 
long : 4 octets «type».
double : 8 octets

● Exemple :
printf("char : %d octets\n", sizeof(char));
printf("int : %d octets\n", sizeof(int));
printf("long : %d octets\n", sizeof(long));
printf("double : %d octets\n", sizeof(double));
L'adressage de la mémoire
Int nombre = 16 ;
51
52

Le nombre d'octets réservés pour un entier = 4 53
54 16

Chaque octet a une adresse. 55
56
57

Quelle est l'adresse de « nombre » ?

L'adresse du premier octet (52)


L'adressage de la mémoire
char lettre = '@' ;
51
52

Le nombre d'octets réservés pour
53
un caracter = 1
54
55

Chaque octet a une adresse.
56 '@'
57

Quelle est l'adresse de « lettre » ?

L'adresse du premier octet (56)


L'adressage de la mémoire
char lettres[4] = '@' ;
51
52

Le nombre d'octets réservés pour 53 '#'
54 '@'
lettres = 4 (octet pour chaque case)
55 '*'
56 '+'

Quelle est l'adresse de « nombre » ? 57

L'adresse du premier octet (53)


Les problèmes de l'allocation statique
● Manque de flexibilité dans la gestion de la mémoire.
– Pas de réservation de la mémoire durant l'exécution.
– Pas de libération de l'espace mémoire dans l'exécution.

● Déclaration des tableaux


– On doit prédir la taille maximale du tableau.
– Gaspillage de l'espace mémoire.
Exemple
● Ecrire un programme qui lit les notes de n étudiants pour
les stocker dans un tableau.
● Le nombre « n » est donné par l'utilisateur durant
l'exécution.
Si le nombre d'étudiant n = 100 !!!!!!!!!!!!!!!
● Solution :
– Pour éviter le dépassement de capacité, on déclare un tableau qui
contient 1000 cases (le nombre d'étudiants ne dépasse pas 1000).
L'allocation dynamique

● Réservation de l'espace mémoire durant l'exécution.


– Réservation manuelle à travers une instruction.

● Libération de l'espace mémoire durant l'exécution.


– Léberation de l'espace à travers une instruction.
Réservation de l'espace
● Utilisation de la fonction C malloc

– void* malloc(size_t nombreOctetsNecessaires);

NombreOctetsNecessaires : nombres d'octets réservés.

● La fonction retourne un pointeur sur l'espace alloué.


● Le pointeur retourné est de type void*.
– Pointeur sans type.
Pointeur void *

On ne peut pas utiliser une variable de


type void * avant de la convertir à un
pointeur avec type.
Les étapes de réservation d'un espace
mémoire
(1) Appel de la fonction malloc.
– Specification du nombre d'octets.

(2) Conversion de la valeur retournée (void *) à un pointeur


avec type (type *).
– Casting.

(3) Verification de la valeur retournée par malloc.


Exemple
#include <stdio.h>
#include <stdlib.h>
int main()
{
    int *ptrSurEntier =NULL;
    ptrSurEntier = (int *)malloc(sizeof(int));
    if(ptrSurEntier!=NULL)
    {
        *ptrSurEntier=16;
        printf("Valeur du pointeur =%d",*ptrSurEntier);
    }
    else
        printf("Réservation échouée");
    return 0;
}
Exemple
int main()

{
*ptrSurEntier NULL
    int *ptrSurEntier =NULL; 50
    ptrSurEntier = (int *)malloc(sizeof(int)); 51
    if(ptrSurEntier!=NULL)
52
    {
53
        *ptrSurEntier=16;

        printf("Valeur du pointeur =%d",*ptrSurEntier); 54
    } 55
    else
56
        printf("Réservation échouée");
57
    return 0;

}
Exemple
int main()

{
*ptrSurEntier 52
    int *ptrSurEntier =NULL; 50
    ptrSurEntier = (int *)malloc(sizeof(int)); 51
    if(ptrSurEntier!=NULL)
52
    {
53
        *ptrSurEntier=16;

        printf("Valeur du pointeur =%d",*ptrSurEntier); 54 ??
    } 55
    else
56
        printf("Réservation échouée");
57
    return 0;

}
Exemple
int main()

{
*ptrSurEntier 52
    int *ptrSurEntier =NULL; 50
    ptrSurEntier = (int *)malloc(sizeof(int)); 51
    if(ptrSurEntier!=NULL)
52
    {
53
        *ptrSurEntier=16;

        printf("Valeur du pointeur =%d",*ptrSurEntier); 54 ??
    } 55
    else
56
        printf("Réservation échouée");
57
    return 0;

}
Exemple
int main()

{
*ptrSurEntier 52
    int *ptrSurEntier =NULL; 50
    ptrSurEntier = (int *)malloc(sizeof(int)); 51
    if(ptrSurEntier!=NULL)
52
    {
53
        *ptrSurEntier=16;

        printf("Valeur du pointeur =%d",*ptrSurEntier); 54 16
    } 55
    else
56
        printf("Réservation échouée");
57
    return 0;

}
Exemple
Valeur de *ptrSurEntier = 16

int main()

{
*ptrSurEntier 52
    int *ptrSurEntier =NULL; 50
    ptrSurEntier = (int *)malloc(sizeof(int)); 51
    if(ptrSurEntier!=NULL)
52
    {
53
        *ptrSurEntier=16;

        printf("Valeur de *ptrSurEntier =%d",*ptrSurEntier); 54 16
    } 55
    else
56
        printf("Réservation échouée");
57
    return 0;

}
Libération de l'espace mémoire

● Lorsque l'espace mémoire devient inutile, on doit le libérer


pour d'autres programmes en utilisant la fonction Free.

Free(nomDePointeur) ;
Exemple
int main()

{
*ptrSurEntier ????
52
    int *ptrSurEntier =NULL; 50
    ptrSurEntier = (int *)malloc(sizeof(int));
51
    if(ptrSurEntier!=NULL)
52
    {
53
16
        *ptrSurEntier=16;

        printf("Valeur de *ptrSurEntier =%d",*ptrSurEntier); 54
        Free(ptrSurEntier)
55
    }

    else
56
        printf("Réservation échouée"); 57
    return 0;

}
Réservation d'un tableau

● Réservation de plusieurs cases

– Utilisation de la fonction malloc avec le paramètre


n*sizeof(type)

– Affectation de l'espace réservé à un pointeur


type *
Accès aux élements du tableau
– Incrémentation du pointeur.
Pointeur++;

– Opérations arithmetiques sur les pointeurs.


Pointeur = Pointeur+i; 
#include <stdio.h>
#include <stdlib.h>
int main()
{
    int *ptrEntier=NULL;
    int n,i;

NULL
    printf("Donnez le nombre de cases à réserver \n");
    scanf("%d",&n); *ptrSurEntier
    ptrEntier = (int *)malloc(n*sizeof(int));
    if(ptrEntier!=NULL)
50
    {
        printf("Charger le tableau avec les valeurs 0 1 ... n \n");
51
        for(i=0;i<n;i++)
52
        {
            *(ptrEntier+i)=i; 53
        }
        printf("Les valeurs du tableau sont : \n"); 54
        for(i=0;i<n;i++)
        { 55
            printf("%d \n",i,*(ptrEntier+i));
        } 56
        free(ptrEntier);
    }
57
    else 58
        printf("Réservation echouée");
    return 0;
59
}
#include <stdio.h>
#include <stdlib.h>
int main()
{

   int *ptrEntier=NULL;

 
   int n,i;
    printf("Donnez le nombre de cases à réserver \n");
    scanf("%d",&n);
*ptrSurEntier NULL
    ptrEntier = (int *)malloc(n*sizeof(int)); 50
    if(ptrEntier!=NULL)
    {
51
        printf("Charger le tableau avec les valeurs 0 1 ... n \n");
        for(i=0;i<n;i++) 52
        {
            *(ptrEntier+i)=i; 53
        }
        printf("Les valeurs du tableau sont : \n"); 54
        for(i=0;i<n;i++)
        { 55
            printf("%d \n",i,*(ptrEntier+i));
        } 56
        free(ptrEntier);
    }
57
    else
        printf("Réservation echouée");
58 N= ???
    return 0;
}
59 I= ???
#include <stdio.h>
#include <stdlib.h>
int main()
{

   int *ptrEntier=NULL;

 
   int n,i;
    printf("Donnez le nombre de cases à réserver \n");
    scanf("%d",&n);
*ptrSurEntier NULL
    ptrEntier = (int *)malloc(n*sizeof(int)); 50
    if(ptrEntier!=NULL)
    {
51
        printf("Charger le tableau avec les valeurs 0 1 ... n \n");
        for(i=0;i<n;i++) 52
        {
            *(ptrEntier+i)=i; 53
        }
        printf("Les valeurs du tableau sont : \n"); 54
        for(i=0;i<n;i++)
        { 55
            printf("%d \n",i,*(ptrEntier+i));
        } 56
        free(ptrEntier);
    }
57
    else
        printf("Réservation echouée");
58 N= ???
    return 0;
}
59 I= ???
#include <stdio.h>
#include <stdlib.h>
int main()
{

   int *ptrEntier=NULL;
    int n,i;
    printf("Donnez le nombre de cases à réserver \n");
    scanf("%d",&n);
*ptrSurEntier NULL
    ptrEntier = (int *)malloc(n*sizeof(int));
50
    if(ptrEntier!=NULL)
    {
51
        printf("Charger le tableau avec les valeurs 0 1 ... n \n");
        for(i=0;i<n;i++) 52
        {
            *(ptrEntier+i)=i; 53
        }
        printf("Les valeurs du tableau sont : \n"); 54
        for(i=0;i<n;i++)
        { 55
            printf("%d \n",i,*(ptrEntier+i));
        } 56
        free(ptrEntier);
    }
57
    else
        printf("Réservation echouée");
58 N= ???
    return 0;
}
59 I= ???
#include <stdio.h>
#include <stdlib.h>
int main()
{

    int *ptrEntier=NULL;

 
   int n,i;
    printf("Donnez le nombre de cases à réserver \n");
    scanf("%d",&n);
*ptrSurEntier 50
    ptrEntier = (int *)malloc(n*sizeof(int)); 50
    if(ptrEntier!=NULL)
    {
51
        printf("Charger le tableau avec les valeurs 0 1 ... n \n");
        for(i=0;i<n;i++) 52
        {
            *(ptrEntier+i)=i; 53
        }
        printf("Les valeurs du tableau sont : \n"); 54
        for(i=0;i<n;i++)
        { 55
            printf("%d \n",i,*(ptrEntier+i));
        } 56
        free(ptrEntier);
    }
57
    else
        printf("Réservation echouée");
58 N= 2
    return 0;
}
59 I= ???
#include <stdio.h>
#include <stdlib.h>
int main()
{

   int *ptrEntier=NULL;

 
   int n,i;
    printf("Donnez le nombre de cases à réserver \n");
    scanf("%d",&n);
*ptrSurEntier 50
    ptrEntier = (int *)malloc(n*sizeof(int)); 50
    if(ptrEntier!=NULL)

51
0
    {
        printf("Charger le tableau avec les valeurs 0 1 ... n \n");
        for(i=0;i<n;i++) 52
        {
            *(ptrEntier+i)=i; 53
        }
        printf("Les valeurs du tableau sont : \n"); 54
        for(i=0;i<n;i++)
        { 55
            printf("%d \n",i,*(ptrEntier+i));
        } 56
        free(ptrEntier);
    }
57
    else
        printf("Réservation echouée");
58 N= 2
    return 0;
}
62 I= 0
#include <stdio.h>
#include <stdlib.h>
int main()
{

   int *ptrEntier=NULL;

 
   int n,i;
    printf("Donnez le nombre de cases à réserver \n");
    scanf("%d",&n);
*ptrSurEntier 50
    ptrEntier = (int *)malloc(n*sizeof(int)); 50
    if(ptrEntier!=NULL)

51
0
    {
        printf("Charger le tableau avec les valeurs 0 1 ... n \n");
        for(i=0;i<n;i++) 52
        {
            *(ptrEntier+i)=i; 53
        }
        printf("Les valeurs du tableau sont : \n"); 54 +4
        for(i=0;i<n;i++)

1
        { 55
            printf("%d \n",i,*(ptrEntier+i));
        } 56
        free(ptrEntier);
    }
57
    else
        printf("Réservation echouée");
58 N= 2
    return 0;
}
62 I= 0
#include <stdio.h>
#include <stdlib.h>
int main()
{

   int *ptrEntier=NULL;

 
   int n,i;
    printf("Donnez le nombre de cases à réserver \n");
    scanf("%d",&n);
*ptrSurEntier 50
    ptrEntier = (int *)malloc(n*sizeof(int)); 50
    if(ptrEntier!=NULL)

51
0
    {
        printf("Charger le tableau avec les valeurs 0 1 ... n \n");
        for(i=0;i<n;i++) 52
        {
            *(ptrEntier+i)=i; 53
        }
        printf("Les valeurs du tableau sont : \n"); 54 +4
        for(i=0;i<n;i++)

1
        { 55
            printf("%d \n",i,*(ptrEntier+i));
        } 56
        free(ptrEntier);
    }
57
    else
        printf("Réservation echouée");
58 N= 2
    return 0;
}
62 I= 0
#include <stdio.h>
#include <stdlib.h>
int main()
{

   int *ptrEntier=NULL;
    int n,i;
    printf("Donnez le nombre de cases à réserver \n");
    scanf("%d",&n);
*ptrSurEntier ????
    ptrEntier = (int *)malloc(n*sizeof(int));
50
    if(ptrEntier!=NULL)
    {
51
        printf("Charger le tableau avec les valeurs 0 1 ... n \n");
        for(i=0;i<n;i++) 52
        {
            *(ptrEntier+i)=i; 53
        }
        printf("Les valeurs du tableau sont : \n"); 54
        for(i=0;i<n;i++)
        { 55
            printf("%d \n",i,*(ptrEntier+i));
        } 56
        free(ptrEntier);
    }
57
    else
        printf("Réservation echouée");
58 N= 2
    return 0;
}
62 I= 2
Résumé

● L'allocation statique se fait par le compilateur.


– Manque de flexibilité.
Résumé

● Allocation dynamique se fait par le programmeur.


– Plus de flexibilité.
● Allocation de l'espace mémoire en utilisant la fonction :
Malloc(nombre d'octoer) ;
● Libération de l'espace mémoire en utilisant la fonction 
Free(nom de pointeur) ;
Résumé

● On peut allouer un tableaeu dynamiquement en utilsant les


pointeurs.

● Lorsque on incrémente le pointeur, on ajoute à son contenu


(adresse) le nombre d'octets correspondant à son type.
Int *p ;
p=p+1 ; <====> contenu de p = contenu de p + 4 (int 4 octets)