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 :

calloc et tableau de pointeurs


Sujet :

C

  1. #1
    Membre éprouvé
    Inscrit en
    Juin 2008
    Messages
    91
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 91
    Par défaut calloc et tableau de pointeurs
    Bonjour,

    Sachant que la norme ne donne pas de sens à une référence mémoire, et indirectement ne définit pas la nature d'un type pointeur; peut-on dire qu'un calloc est (sensé/judicieux) dans un cas comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    int **ptr;
     
    ptr = calloc(taille);
    On met tous les bits alloués à 0; on sait que ce n'est pas prudent de le faire pour des nombres à virgules flottante, qu'est-ce qu'on peut dire pour les pointeurs ?

    Merci par avance.

  2. #2
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Ce que dit la norme n1256 en note de bas de page :

    7.20.3.1 : The calloc function
    ....
    The space is initialized to all bits zero.261)
    ....
    261) Note that this need not be the same as the representation of floating-point zero or a null pointer constant.

  3. #3
    Membre éprouvé
    Inscrit en
    Juin 2008
    Messages
    91
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 91
    Par défaut
    Merci pour ta réponse,

    Au risque de confusion, j'hésite entre les deux interprétations suivantes, si tu veux bien m'en confirmer une :

    les bits sont initialisés à 0; notez que ça n'a pas besoin d'avoir la même représentation d'un zéro (à virgule flottante) ou un pointeur nul.
    Auquel cas on peut l'utiliser sans soucis.

    les bits sont initialisés à 0; notez que ça n'a pas nécessairement la même représentation d'un zéro (à virgule flottante) ou un pointeur nul.
    Cette interprétation peut pousser à éviter ce genre de pratiques.

    Merci.

  4. #4
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Ca veut dire qu'utiliser calloc() pour initialiser une zone qui contient des pointeurs ou des flottants n'est pas portable, et ne donnera pas forcément le résultat attendu sur toutes les architectures.

    En pratique ça fonctionne sur la plupart des architectures courantes. Je sais que j'utilise souvent calloc() pour initialiser des structures qui contiennent des pointeurs, mais la portabilité n'est pas un problème pour moi.

  5. #5
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 102
    Par défaut
    j'aimerais avoir une précision:
    pour faire une allocation "sécurisée" et portable il vaut donc mieux utiliser malloc et faire un memset derrière pour initialiser ? (est ce que cette initialisation est "propre" quelque soit le type ? sinon, existe t-il une bonne méthode secure pour initialiser une mémoire ? )

    mais alors calloc ne servirait qu'à éviter d'écrire 2 lignes ? Elle n'ajoute rien au niveau sécurité ?

    edit: je viens de lire ça , et j'avoue que je ne comprend pas bien la partie en gras:
    ce n'est pas parce que la fonction calloc() met les bits du bloc mémoire alloué à 0 que la valeur de la variable alloué est forcément égale à 0. La norme n'impose en effet aucune chose là dessus. Il se trouve qu'ici nous avons des entiers et dans la très grande majorité des cas le fonctionnement sera identique à ce que nous avons : les entiers valent 0. Cependant, il sera plus difficile de faire la même chose avec des nombres réels. On pourra avoir un nombre réel qui a tous ces bits à 0 de manière interne mais qui ne vaut pas forcément 0. Il faudra donc faire attention à ne pas trop se reposer sur calloc()
    je n'arrive pas à saisir qu'un octet qui vaut 00000000 n'ai pas sa valeur = 0...
    et puis si ce problème existe avec calloc(), pourquoi n'existe t-il pas avec memset() ?

  6. #6
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Le problème existe aussi avec memset(). malloc() + memset() n'est plus sûr ou plus portable ou plus propre que calloc().

    Le truc c'est que dans la norme, rien ne garanti que NULL est codé sous la forme d'octets à 0. Et d'ailleurs il y a eu des plateformes (il y en a peut-être encore, je ne sais pas), ou NULL n'est pas formé d'octets à 0. Par contre dans tous le cas la norme assure qu'on a toujours NULL == 0, et qu'on peut aussi écrire "ptr = 0" pour initialiser un pointeur à NULL. Mais dans ce cas on a un cast, et le compilateur sait quelle séquence de bits il doit stocker en mémoire pour former un NULL. En C "x = 0" ne veut pas dire "mettre les bits de x à 0", mais "mettre x à sa valeur nulle". Par contre si tu utilises un calloc ou un memset pour initialiser un pointeur à 0, alors tu écris vraiment des 0 en mémoire, et ça ne forme par forcément un NULL.

    Si une structure à des champs de type "pointeur" que tu souhaite initialiser à NULL, les seules façon portable de le faire sont :

    - Si la variable est allouée dynamiquement, mettre explicitement chaque champs à 0 avec des lignes du genre "mystruct->ptr = NULL"
    - Si la variable est automatique (dans la stack), tu peux aussi utiliser un initialiseur du type "struct T mystruct = { 0 };". Ca marche parce que le compilo sait exactement comment mettre chaque champs à 0.
    - Si la variable est globale, tu n'as rien besoin de faire puisqu'elle est déjà initialisée à 0.

    Note bien que le problème ne se pose pas seulement pour les pointeurs. Tu pourrait aussi avoir le même genre de problème avec, par exemple, des flottant. La valeur "0" n'est pas forcément codée sous la forme de bits à 0.

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

Discussions similaires

  1. Tableau de pointeur de fonction
    Par Gryzzly dans le forum C
    Réponses: 7
    Dernier message: 31/12/2005, 10h47
  2. Tableau de pointeurs sur objets
    Par bassim dans le forum C++
    Réponses: 11
    Dernier message: 13/12/2005, 19h45
  3. [GCC] Tableau de pointeurs pour accès multiples en asm
    Par Flo. dans le forum x86 32-bits / 64-bits
    Réponses: 2
    Dernier message: 12/12/2005, 08h47
  4. tableau de pointeurs
    Par seal3 dans le forum C++
    Réponses: 7
    Dernier message: 01/11/2005, 20h51
  5. Tableau de pointeurs de fonctions
    Par Alp dans le forum C++
    Réponses: 7
    Dernier message: 29/10/2005, 13h19

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