IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Bien comprendre l'allocation dynamique


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Profil pro
    Étudiant
    Inscrit en
    Avril 2007
    Messages
    181
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2007
    Messages : 181
    Par défaut Bien comprendre l'allocation dynamique
    Bonjour,

    J'ai vu en cours les fonctions malloc() et free(), ainsi que le concept de tableau à taille dynamique.

    1) Ce code permet d'augmenter la taille du tableau de 10 postes supplémentaires à chaque appel de la fonction agrandir (aucune valeur n'est manipulée dans le tableau mais le principe est là).
    Ma façon de procéder est-elle correcte ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    40
    #include <stdlib.h>
    #include <stdio.h>
     
     
    int* agrandir(int tab[], int *taille)
    {
    	int *t_temp = NULL;
    	int i = 0;
     
    	t_temp = (int*) malloc(sizeof (int) * (*taille + 10));
    	/* on recopie les valeurs dans le nouveau tableau */
    	for (i=0; i < *taille; i++)
    	{
    		t_temp[i] = tab[i];
    	}
     
    	*taille += 10;
    	free(tab);
     
    	/* on retourne la nouvelle adresse de tab */
    	return t_temp;
    }
     
     
    int main()
    {
    	int *tab = NULL;
    	int taille=0;
     
    	tab = (int*) malloc(sizeof (int) * 50);
    	taille = 50;
     
    	printf("nombre de postes : %d\n", taille);
     
    	tab = agrandir(tab, &taille);
    	printf("nombre de postes : %d\n", taille);
    	free(tab);
     
    	return 0;
    }
    2) Je me suis un peu documenté (man malloc et FAQ C) et j'ai vu la fonction realloc, qui m'a l'air de faire la même chose.
    Est-ce le cas ?

    3) J'ai aussi une question sur le fonctionnement de la fonction free :
    Quand on déclare un tableau à dimension fixe
    tableau est de type int[50] donc le langage sait que 50 postes int sont réservés en mémoire à partir de l'adresse de tableau.
    Mais si on veut une taille dynamique, tableau est déclaré avec :
    donc le type est int*, alors comment fait la fonction free pour libérer la mémoire si la taille n'est stockée nulle part ?
    Mes professeurs m'ont dit que c'est parce que la mémoire vive possède une zone "différente" qui est réservée aux allocations dynamiques... mais je ne vois pas le rapport.
    Comment free connaît le nombre de postes à libérer à partir de l'adresse qui lui est passée en argument ?


    Merci

  2. #2
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Haze. Voir le message
    J'ai vu en cours les fonctions malloc() et free(), ainsi que le concept de tableau à taille dynamique.

    1) Ce code permet d'augmenter la taille du tableau de 10 postes supplémentaires à chaque appel de la fonction agrandir (aucune valeur n'est manipulée dans le tableau mais le principe est là).
    Ma façon de procéder est-elle correcte ?
    Il est techniquement possible de faire comme tu as fais, mais il est préférable d'utiliser realloc(). D'autre part, il faut toujours tester ce que retourne les fonctions d'allocation. Un échec est toujours possible (NULL).

    http://emmanuel-delahaye.developpez....tes.htm#malloc
    http://emmanuel-delahaye.developpez....es.htm#realloc
    3) J'ai aussi une question sur le fonctionnement de la fonction free :
    Quand on déclare un tableau à dimension fixe
    tableau est de type int[50] donc le langage sait que 50 postes int sont réservés en mémoire à partir de l'adresse de tableau.
    Exact. En fait, la taille est une expression constante qui est utilisée pour générer du code où tout adressage est pré-calculé par le compilateur (quand c'est possible). On gagne en vitesse et en taille de code, mais on perd en souplesse.
    Mais si on veut une taille dynamique, tableau est déclaré avec :
    donc le type est int*, alors comment fait la fonction free pour libérer la mémoire si la taille n'est stockée nulle part ?
    Mes professeurs m'ont dit que c'est parce que la mémoire vive possède une zone "différente" qui est réservée aux allocations dynamiques... mais je ne vois pas le rapport.
    Comment free connaît le nombre de postes à libérer à partir de l'adresse qui lui est passée en argument ?
    Faut pas trop en demander à un prof standard...

    Lors de la demande d'allocation mémoire (*alloc()), on passe une taille qui, si l'allocation réussit, est probablement enregistrée 'quelque part', associée à l'adresse du bloc alloué. Lors du free(), l'adresse est recherchée et le bloc est libére. Mais je ne suis même pas sûr que la taille du bloc conservée... C'est un provblème d'implémentation qui ne concerne pas le programmeur.

    Si on veut connaitre la taille du bloc alloué, soit on initialise le bloc avec une valeur et on met une 'sentinelle' au bout qui soit différente de cette valeur (genre chaine de caractères...), mais ça 'bloque' une valeur, soit on prend les précautions nécessaires pour conserver la taille. Le plus évident est de créer une structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct tabdyn
    {
       T *tab;
       size_t nb_elem;
    };

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 299
    Par défaut
    Salut,
    les cast lors du malloc ne servant à rien
    teste si le malloc ne t'as pas renvoyé NULL
    pour un malloc, il vaut mieux faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int * pint=malloc(N*sizeof(*pint))
    if(pint==NULL)
    {
    /* erreur */
    }
    c'est mieux que de faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int * pint=malloc(N*sizeof(int))
    if(pint==NULL)
    {
    /* erreur */
    }
    car si tu changes le type de pint, tu ne changeras rien dans le malloc...

  4. #4
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par Haze. Voir le message
    Comment free connaît le nombre de postes à libérer à partir de l'adresse qui lui est passée en argument ?
    Voir cette discussion.

  5. #5
    Membre expérimenté
    Profil pro
    Étudiant
    Inscrit en
    Avril 2007
    Messages
    181
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2007
    Messages : 181
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Il est techniquement possible de faire comme tu as fais, mais il est préférable d'utiliser realloc()
    Comme je n'ai pas vu cette fonction en cours, je voulais m'assurer d'avoir compris le principe de la taille dynamique

    Citation Envoyé par Emmanuel Delahaye
    D'autre part, il faut toujours tester ce que retourne les fonctions d'allocation. Un échec est toujours possible (NULL).
    Citation Envoyé par salseropom
    teste si le malloc ne t'as pas renvoyé NULL
    Oui en effet... je ferais attention dorénavant. J'enlèverai aussi les casts devant l'appel de malloc.

    Merci à tous pour vos réponses très instructives.

    Citation Envoyé par Emmanuel Delahaye
    Faut pas trop en demander à un prof standard...
    Ho... je dirai plutôt, prof anti-standards.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. probleme d'allocation dynamique
    Par vince3320 dans le forum C
    Réponses: 10
    Dernier message: 22/04/2004, 16h27
  2. petit pbm allocation dynamique de stringGrid
    Par AnneOlga dans le forum C++Builder
    Réponses: 10
    Dernier message: 17/01/2004, 11h59
  3. Allocation dynamique de structures
    Par fr_knoxville dans le forum C
    Réponses: 8
    Dernier message: 06/05/2003, 21h59
  4. Allocation dynamique de mémoire en asm
    Par narmataru dans le forum Assembleur
    Réponses: 7
    Dernier message: 17/12/2002, 22h31
  5. Réponses: 4
    Dernier message: 03/12/2002, 16h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo