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

Bibliothèque standard C Discussion :

Taille d'allocation de Malloc


Sujet :

Bibliothèque standard C

  1. #1
    Membre à l'essai
    Inscrit en
    Janvier 2004
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 18
    Points : 17
    Points
    17
    Par défaut Taille d'allocation de Malloc
    Je cherche a comprendre pourquoi cet utilisation de malloc fonctionne, mais ne devrait pourtant pas fonctionner?


    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
     
    typedef struct
    {
    	unsigned int entry_start;
    	unsigned int entry_end;
    }ENTRY;
     
     
    int main(int argc, char *argv[])
    {
        ENTRY *file_entry;
        int i;
     
     
        file_entry  = malloc(0);
       for (i=0;i<35;i++)
        {
           file_entry[i].entry_start = i;
           file_entry[i].entry_end = i+1;       
        }  
     
        for (i=0;i<35;i++)
        {
            printf("entry start : %d entry end : %d\n", file_entry[i].entry_start, file_entry[i].entry_end );  
        }    
     
        system("PAUSE");   	
        return 0;
    }
    Si j'arrête la boucle a 36 ou +, là par contre sa ne fonctionne plus, des explication?

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Salut.

    Le comportement est défini par l'implémentation.

    La norme C90 n'est pas très loquace à ce sujet :
    If the size of the space requested is zero, the behavior is implementation defined; the value returned shall be either a null pointer or a unique pointer.
    La norme ne définit pas ce qu'est ce fameux "unique pointer"... ou alors peut-être de manière détournée (?). Les connaisseurs donneront sûrement des précisions.

    Par contre C99 précise mieux les choses :
    If the size of the space requested is zero, the behavior is implementation-defined: either a null pointer is returned, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object.
    Cela veut dire que si la fonction renvoie autre chose que NULL ce pointeur ne devra pas être utilisé pour accéder à l'objet. Mais le "the behavior is as if the size were some nonzero value" laisse supposer qu'il s'agit d'un pointeur valide, dans le sens où on peut ensuite l'utiliser avec free.

    Mais dans la pratique je ne vois de toute façon pas l'intérêt d'allouer 0 byte de mémoire.
    J'ai une question à mon tour : pourquoi la norme permet-elle ce cas spécial ? Pour laisser un peu de souplesse à l'implémentation ?

  3. #3
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 371
    Points : 23 626
    Points
    23 626
    Par défaut
    Bonjour,

    Citation Envoyé par jeroman Voir le message
    J'ai une question à mon tour : pourquoi la norme permet-elle ce cas spécial ? Pour laisser un peu de souplesse à l'implémentation ?
    J'imagine que c'est utile lorsque la quantité de mémoire à réserver est déterminé par calcul à l'exécution (du style « malloc(nombredelements * sizeof element) »). Dans le cas d'une liste vide, il est idiot d'allouer de la mémoire pour rien, mais il faut quand même que le pointeur soit valide pour ne pas mettre en échec le programme qui fait cet appel.

    Dans ce cas, soit on renvoie effectivement NULL, soit on réserve à l'avance un octet « permanent » à l'aide d'une variable globale ou une locale statique, qui serve de « parking » et dont on renverrait l'adresse — toujours la même — à tous les malloc(0). Je pense que c'est ce qu'ils entendent par « pointeur unique ».

  4. #4
    Membre à l'essai
    Inscrit en
    Janvier 2004
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 18
    Points : 17
    Points
    17
    Par défaut
    En fait, au début je me demandais si j'allouais vraiment le bon espace, je me suis mis a faire des test, et peu importe la valeurs que je lui met, sa semble être faux, même si je met malloc(1)... je peut utiliser 35 éléments, pourtant au deuxième, sa devrait ne pas fonctionner...

  5. #5
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par eric30eric Voir le message
    En fait, au début je me demandais si j'allouais vraiment le bon espace, je me suis mis a faire des test, et peu importe la valeurs que je lui met, sa semble être faux, même si je met malloc(1)... je peut utiliser 35 éléments, pourtant au deuxième, sa devrait ne pas fonctionner...
    C'est un comportement indéfini, tout peut arriver y compris un code qui semble marcher (jusqu'au jour où).

  6. #6
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Dans ce cas, soit on renvoie effectivement NULL, soit on réserve à l'avance un octet « permanent » à l'aide d'une variable globale ou une locale statique, qui serve de « parking » et dont on renverrait l'adresse — toujours la même — à tous les malloc(0). Je pense que c'est ce qu'ils entendent par « pointeur unique ».
    pointeur unique c'est que chaque malloc(0) en renvoie un différent (jusqu'à ce qu'il soit libéré). Voir la citation de Jeroman.

    Citation Envoyé par eric30eric Voir le message
    En fait, au début je me demandais si j'allouais vraiment le bon espace, je me suis mis a faire des test, et peu importe la valeurs que je lui met, sa semble être faux, même si je met malloc(1)... je peut utiliser 35 éléments, pourtant au deuxième, sa devrait ne pas fonctionner...
    Formellement, tu fais quelque chose que tu ne dois pas, n'importe quoi peut arriver, y compris fonctionner comme tu penses que ça devrait.

    En pratique, tu as vraisemblablement foutu en l'air les structures de données utilisées par malloc, mais ça se verra plus tard quand tu auras fais d'autres allocations/déallocations.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 371
    Points : 23 626
    Points
    23 626
    Par défaut
    Citation Envoyé par eric30eric Voir le message
    même si je met malloc(1)... je peut utiliser 35 éléments, pourtant au deuxième, sa devrait ne pas fonctionner...
    Un début d'explication ici : http://www.developpez.net/forums/d88...e/#post5018145

    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    pointeur unique c'est que chaque malloc(0) en renvoie un différent (jusqu'à ce qu'il soit libéré). Voir la citation de Jeroman.
    Mouais. Ça ne me convainc pas. Je reste à peu près persuadé que l'auteur du paragraphe de la première norme le voyait à peu près comme je le vois, avant que ce point ambigu ne soit clarifié dans C99 et qu'il y soit décidé de faire en sorte que les pointeurs renvoyés, si non NULL, se comportent de la même façon dans tous les cas…

  8. #8
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Mouais. Ça ne me convainc pas. Je reste à peu près persuadé que l'auteur du paragraphe de la première norme le voyait à peu près comme je le vois, avant que ce point ambigu ne soit clarifié dans C99 et qu'il y soit décidé de faire en sorte que les pointeurs renvoyés, si non NULL, se comportent de la même façon dans tous les cas…
    Voir le rationale, la rédaction est un compromis entre les tenants du "il n'y a pas d'objets de taille nulle, donc un malloc() de taille 0 est une erreur", et "il y a des objets de taille nulle, donc un malloc() de taille 0 renvoie un pointeur différent de tous les autres pointeurs valides".

    Pour corroborer: l'implémentation de malloc() de Plauger dans The Standard C Library (1991) commence par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if (size <  SIZE_CELL)
       size = SIZE_CELL;
    et il était le président de sous-comité "librairie" avant de prendre celle du comité au complet.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  9. #9
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Il me semble que malloc, en plus de réserver de la mémoire, crée une entête. Donc, ça ne me parait pas contradictoire de prévoir dans la norme d'exécuter malloc, même si l'espace nécessaire à réserver est nul.
    Par contre, à moins de tester explicitement les fonctions de base, malloc en l'occurrence, cette instruction malloc(0) n'a pas de sens. Pourquoi un développeur voudrait-il réserver explicitement un bloc mémoire de taille zéro? En plus de la syntaxe, la programmation sous-entend une certaine logique.
    C'est d'autant plus étonnant que dans la suite du code il utilise cette mémoire, comme s'il l'avait réellement réservée.
    Il y a une certaine probabilité que une certaine quantité d'octets qui suivent l'adresse du pointeurs ne soient pas utilisés ACTUELLEMENT. Mais on ne peut pas dire, et en aucun cas, que ca marche.
    Vous garez votre voiture sur un espace pompier, tant qu'il n'y aura ni incendie ni police, pouvez-vous dire "On peut se garer sur un espace pompier"?

  10. #10
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 371
    Points : 23 626
    Points
    23 626
    Par défaut
    Citation Envoyé par Pierre Dolez Voir le message
    Il me semble que malloc, en plus de réserver de la mémoire, crée une entête. Donc, ça ne me parait pas contradictoire de prévoir dans la norme d'exécuter malloc, même si l'espace nécessaire à réserver est nul.
    Ça, c'est une question d'implémentation. Ce n'est pas spécifié par la norme. De plus, rien n'impose aux méta-données d'être contiguës à l'espace réservé. Je sais que ça se faisait sous DOS, oui, mais ailleurs, il est plus censé, à mon goût, de maintenir une map à un seul endroit gardant trace de tous les pointeurs renvoyés et des plages correspondantes.

    Par contre, à moins de tester explicitement les fonctions de base, malloc en l'occurrence, cette instruction malloc(0) n'a pas de sens. Pourquoi un développeur voudrait-il réserver explicitement un bloc mémoire de taille zéro? En plus de la syntaxe, la programmation sous-entend une certaine logique.
    On a déjà donné un exemple plus haut. Il faut relire le fil en entier avant de poster.

Discussions similaires

  1. Réponses: 10
    Dernier message: 24/06/2014, 16h57
  2. Problème de choix d'allocation new/malloc
    Par Awakening dans le forum Langage
    Réponses: 3
    Dernier message: 25/02/2011, 09h32
  3. [x86-64] Allocation dynamique (malloc) et heap
    Par xion.luhnis dans le forum x86 32-bits / 64-bits
    Réponses: 5
    Dernier message: 23/10/2010, 19h23
  4. Problème allocation mémoire - malloc () 1Gb
    Par Gellius31 dans le forum Bibliothèque standard
    Réponses: 14
    Dernier message: 21/12/2007, 12h16
  5. Pb d'allocation mémoire malloc
    Par oz80 dans le forum C++
    Réponses: 5
    Dernier message: 18/11/2005, 17h23

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