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 :

Malloc et les pointeurs **


Sujet :

C++

  1. #1
    Futur Membre du Club
    Inscrit en
    Avril 2010
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 8
    Points : 7
    Points
    7
    Par défaut Malloc et les pointeurs **
    Bonjour

    Est ce que quelqu'un peut m'expliquer pour quoi on a utilisé deux étoiles au lieu d'une **(**tab) dans la fonction Init suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void Init(double **tab, int nb)
    {
    	*tab = (double*) malloc(nb*sizeof(double));
    }



    merci

  2. #2
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    Tout simplement parce que si on avait mis qu'une seule étoile le code ne fonctionnerait pas.

    Il s'agit du problème du passage des paramètres à une fonction. Le langage C ,comme le C++, passent leur paramètres par copie (sauf si on utilise une référence). Par conséquent, tab est une copie d'un pointeur qu'on a passé en paramètres. Si tu enlève une étoile, tu ne fera qu'affecter la copie du pointeur et pas le pointeur original.

    Fais un dessin avec des flèches et tu verras, c'est évident.

  3. #3
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Le mieux restant d'utiliser les std::vector et new[] et les références si on a pas d'autres choix.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  4. #4
    Futur Membre du Club
    Inscrit en
    Avril 2010
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 8
    Points : 7
    Points
    7
    Par défaut
    Bonjour,
    merci de votre réponse ( .

    cordialement .

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    195
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 195
    Points : 115
    Points
    115
    Par défaut
    Sans les deux * le code est parfaitement fonctionnel. Il n'a peut etre pas le resultat escompté.

  6. #6
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    Sans les deux * le code est parfaitement fonctionnel. Il n'a peut etre pas le resultat escompté.
    Depuis quand c'est fonctionnel ?

    Le code sans l'étoile initialise une variable locale : l'adresse de retour du malloc est perdue à la fin de la fonction. Ca ne peut pas fonctionner à moins d'aller à l'encontre de quelques dizaines d'années de développement en C et C++ : Le passage des paramètres est fait par copie.

    Prend un papier et un crayon, ou bien prend un cours mais il est évident que ça ne peut pas fonctionner.

  7. #7
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Citation Envoyé par PRomu@ld Voir le message
    Depuis quand c'est fonctionnel ?

    Le code sans l'étoile initialise une variable locale : l'adresse de retour du malloc est perdue à la fin de la fonction. Ca ne peut pas fonctionner à moins d'aller à l'encontre de quelques dizaines d'années de développement en C et C++ : Le passage des paramètres est fait par copie.

    Prend un papier et un crayon, ou bien prend un cours mais il est évident que ça ne peut pas fonctionner.
    Je pense que pour lui Fonctionnel = ca compile, pas Ca fait ce que ca devrait faire en théorie
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    195
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 195
    Points : 115
    Points
    115
    Par défaut
    En effet fonctionnel décris manifestement le comportement du programme. Un code qui crash tout le temps est non fonctionnel. un code qui crash de temps en temps est instable. Un code qui ne crash pas est parfaitement fonctionnel.

    Malheuresement et je suis d'accord avec toi si on enleve l'étoile la fonction ne sert a rien. A part a générer une fuite mémoire.

    Désolé si je ne me suis pas fait comprendre, mais un individu tombant sur ta réponse se fera sans doute une mauvaise idée ( le programme crash ).

  9. #9
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Le fait est que, si tu ne passe pas un pointeur de pointeur à cette fonction, tu auras peut être un code qui compile, mais tu aura surtout énormément d'autres problèmes, dont, principalement, celui que l'on peut raisonnablement penser que la valeur passée comme paramètre pour nb (selon l'exemple) sera considérée comme... le nombre d'éléments que peut contenir ton tableau.

    A partir de là, tu as donc de très grandes chances d'alller taper dans une adresse mémoire invalide (à taille réelle + N) et donc, d'avoir un comportement totalement indéfini, parfois juste inaperçus, parfois clairement problématique.

    La première règle à garder en mémoire est donc qu'un code qui compile ne signifie pas un code exempt d'erreur parce qu'il peut simplement... respecter la syntaxe du langage.

    Or, à l'extrême limite, je préfère un code qui ne compile pas à un code qui ne fait pas ce que l'on attend de lui, car, au moins, on est prévenu que l'on a fait une erreur (et les messages émis par le compilateur nous permettent généralement de la situer plus ou moins )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    195
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 195
    Points : 115
    Points
    115
    Par défaut
    Certes !
    Ce n'est à ce que je vois qu'un soucis de vocabulaire. Je peux rappelé que ce code compile parfaitement mais le programme ne crashera pas si on n'utilise pas le tableau. Donc pour moi le code est fonctionnel et c'est uniquement dans ce sens que je parle.

    Bien sur sans l'étoile la fonction n'est qu'une absurdité sans nom. De la a dire que le code ne fonctionnera pas c'est un peu beaucoup s'avancer étant donné notre connaissance du code qui pour l'instant se réduit à une seule fonction.

    Bref mieux vaut prévenir que guérir et je pense que en effet cela est plus judicieux de classer ce code dans la catégorie des "non fonctionnel".

  11. #11
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Tu peux carrément le classer dans la catégorie des codes à très haut risque (pour ne pas dire dans celle des codes qui devraient être interdits), la question n'étant plus de savoir SI l'application plantera, mais QUAND elle le fera, car une chose est sure, elle le fera

    Aller prétendre qu'un code est fonctionnel lorsque l'on ne regarde qu'une fonction dont on se rend compte par ailleurs qu'elle va poser un tas de problèmes est de la pure inconscience, car toute fonction ne vaut que... parce qu'elle est utilisée par d'autres
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    195
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 195
    Points : 115
    Points
    115
    Par défaut
    car toute fonction ne vaut que... parce qu'elle est utilisée par d'autres
    Sur ce point je ne suis pas tout a fais d'accord. Un tas d'expert code des fonctions dont eux seuls comprennent le fonctionnement. Pour donner l'exemple de Carmack et de sa fonction qui calcule l'inverse d'une racine carré, avant que le code soit open source il était le seul detenteur du secret 5 plus ou moin trouvé par son "pote" de NVidia. La fonction cela dit est fortement dépendant de l'architecture et donc peut se trouver instable dans certain cas. Pourtant c'est elle qui à fait son succés.

    la question n'étant plus de savoir SI l'application plantera, mais QUAND elle le fera, car une chose est sure, elle le fera
    Ce point la aussi me chagrine. Je peux te garantir que un code avec uniquement cette fonction je dis bien uniquement ( sans utiliser le tab ou quoique ce soit" ne plantera à aucune execution.

    Tu peux carrément le classer dans la catégorie des codes à très haut risque (pour ne pas dire dans celle des codes qui devraient être interdits)
    Sur ce point tu as raison ( je me permets de te tutoyer :s ).
    Et c'est la la clé de la question, Certes le code compile et fonctionne dans certain cas, de l'autre côté c'est la pure inconscience.

  13. #13
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par nightwar Voir le message
    Sur ce point je ne suis pas tout a fais d'accord. Un tas d'expert code des fonctions dont eux seuls comprennent le fonctionnement. Pour donner l'exemple de Carmack et de sa fonction qui calcule l'inverse d'une racine carré, avant que le code soit open source il était le seul detenteur du secret 5 plus ou moin trouvé par son "pote" de NVidia. La fonction cela dit est fortement dépendant de l'architecture et donc peut se trouver instable dans certain cas. Pourtant c'est elle qui à fait son succés.
    Une fonction calculant l'inverse d'une racine carrée ne vaudrait que... parce qu'elle rend un service clairement identifié et... qu'elle est utilisée "par ailleurs" afin de disposer du dit service.

    Or, si la fonction ne prenait qu'un pointeur simple, elle ne rendrait pas le service que l'on attend d'elle et ne peut donc, purement et simplement, pas être validée en utilisation, y compris durant la période de tests unitaires.

    On ne peut donc absolument pas considérer la fonction comme "fonctionnelle", et ce, quelle que soit le sens que l'on voudra donner au terme: c'est une fonction qui compile parce qu'elle respecte la syntaxe imposée par le langage, mais cela s'arrête là: la fonction est erronée et donc non fonctionnelle (au minimum, car, comme je l'ai dit, elle est même super dangereuse )
    Ce point la aussi me chagrine. Je peux te garantir que un code avec uniquement cette fonction je dis bien uniquement ( sans utiliser le tab ou quoique ce soit" ne plantera à aucune execution.
    Il est clair que, si tu n'a que cette seule fonction, elle ne sera jamais exécutée...

    Mais, si une fonction n'est jamais exécutée, pourquoi "perdre son temps" à la coder

    La question n'est donc pas de savoir si elle est exécutée ou non (car, même lorsque tu crées une bibliothèque, tu fournis des fonctions parce que... tu estimes qu'elles seront utiles et donc utilisées) mais quand elle le sera... et avec quel résultat.

    Or le seul résultat prévisible de la fonction, quelle que soit l'échéance, est un comportement indéfini

    ( je me permets de te tutoyer :s ).
    Fais seulement, je ne me sens pas vieux assez pour être vouvoyé
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  14. #14
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    En effet fonctionnel décris manifestement le comportement du programme. Un code qui crash tout le temps est non fonctionnel. un code qui crash de temps en temps est instable. Un code qui ne crash pas est parfaitement fonctionnel.
    Fonctionnel, c'est étymologiquement qui fonctionne : qui réalise sa fonction. Ici ça n'est pas le cas. Au mieux tu as une fuite mémoire si tu ne veux pas utiliser ce qui a été alloué. En règle générale, le code plantera lamentablement (après cette fonction) parce qu'on aura essayé de taper dans une case mémoire qui n'est pas allouée.

    Bien sur sans l'étoile la fonction n'est qu'une absurdité sans nom.
    Ce qui est surtout absurde c'est d'être dans le forum C++ et être en train de discuter d'un problème de C et qui est réglé depuis longtemps en C++ (cf. référence).

    Pour donner l'exemple de Carmack et de sa fonction qui calcule l'inverse d'une racine carré, avant que le code soit open source il était le seul detenteur du secret 5 plus ou moin trouvé par son "pote" de NVidia.
    En fait, le secret si tant est qu'on puisse parler de secret était déjà connu à l'avance, tu sais comme qu'il s'agit d'une exploitation d'IEEE 754, et que le résultat était plus ou moins déjà mis en évidence dans d'autres papiers antérieurs. Mais bon dieu Carmack avait LA solution ... du coup on a oublié les autres.
    Pour en revenir à cette fonction, elle marche très bien dans les cas d'utilisation qui ont été prévu par Carmack. (c'est parfaitement décris). D'ailleurs tout ça pour dire qu'il faut absolument indiquer les cas d'utilisation de ses fonctions dans les spécifications (donc notamment dans les commentaires) si ceux-ci ne sont pas explicites.

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    195
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 195
    Points : 115
    Points
    115
    Par défaut
    D'accord avec les deux derniers posts.

    Il est évident que sur un forum de C++ on parle de C++ et donc de code réutilisable.Ce que j'essayai de dire est que le résultat de cette fonction sera un crash ou une fuite mémoire simple ou les deux, cela dépend de l'utilisation qui suit l'appel de cette fonction. Ce que je voudrais éviter est que un débutant ( car il s'agit bien de cela ici : aucune offense tout le monde passe par la) pense que fuite mémoire = crash. Beaucoup de code présente des fuites mémoires et ne crash pas si souvent que cela.

    Juste la distinction entre fonction trés dangereuse car inutilisable ( en imaginant que sa véritable fonction est d'initialiser un pointeur passé en paramètre) et fonction qui crash lamentablement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int tab[] = { 1,2,3};
    tab[3] = 9;
    Sentez vous la différence que je veux exposer ?

    Sa fonction est syntaxiquement correcte, fonctionnel mais ne fais pas ce qu'on lui demande et de plus est dangereuse.

    Je me suis permis de chercher la définition du mot " fonctionnel " et il est dit de quelque chose de fonctionnel, quelque chose qui est en état de marche qui fonctionne avec un joli exemple :

    Cet ascenseur marche -t -il ?
    Il y a clairement la différence entre " marche - t -il ? " et " marche - t -il bien ?". Dans le premier cas il est à l'arret = non fonctionnel. Dans le second il marche mais nous emene à l'étage erroné = fonctionnel.

    Je pense néanmoins que cela reste du chipotage. Les esprits des débutant sont assez fragile nous le savons tous, les mots ont une grande importance à ce stade la.

  16. #16
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    les mots ont une grande importance à ce stade la.
    Tout à fait, ce que tu mets en exergue, c'est la différence entre l'exactitude syntaxique et sémantique.

  17. #17
    Membre actif
    Avatar de TheDrev
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2006
    Messages : 310
    Points : 263
    Points
    263
    Par défaut
    cela pourrait fonctionner en retournant l'adresse nouvellement allouée.
    all your base are belong to us.

  18. #18
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par TheDrev Voir le message
    cela pourrait fonctionner en retournant l'adresse nouvellement allouée.
    Il y a plusieurs solutions pour que la fonction puisse faire ce que l'on attend d'elle, mais une chose est sure: en l'état, elle est totalement inadaptée et dangereuse au point de devoir être refusée
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. [LG]Les pointeurs: Forme en "Anneaux"
    Par k o D dans le forum Langage
    Réponses: 4
    Dernier message: 20/10/2004, 07h29
  2. Réponses: 4
    Dernier message: 13/08/2004, 18h39
  3. [TTreeView] Problème avec les pointeurs d'objet
    Par BlackWood dans le forum Composants VCL
    Réponses: 2
    Dernier message: 02/07/2004, 14h31
  4. pointeurs, toujours les pointeurs :/
    Par giviz dans le forum C
    Réponses: 16
    Dernier message: 08/10/2003, 15h02
  5. Pb de débutant sur les pointeurs!!!
    Par benji17c dans le forum C
    Réponses: 6
    Dernier message: 30/09/2003, 17h50

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