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 :

difficulté à passer des pointeurs en arguments


Sujet :

C++

  1. #1
    Membre très actif Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Par défaut difficulté à passer des pointeurs en arguments
    Bonjour, j'ai un petit soucis de pointer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void truc()
    {
        int* hh = (int*)malloc(sizeof(int));
        *hh = 42;
        cout << "address : " << &hh << endl;
        initializeTest(hh);
    }
     
    void initializeTest(int* h)
    {
        cout << "address : " << &h << endl;
    }
    Dans cette exemple, mes 2 adresses sont différentes. Comment cela ce fait-il ?
    Ça fais maintenant plusieurs années que je code en C++ mais là j'ai l'impression de ne pas avoir compris un truc basique (je me sens nul)

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Salut,

    En fait, c'est pour une raison tout à fait idiote: il faut bien que l'adresse mémoire représentée par ton pointeur soit accessible au travers... d'une variable ( qui sera, typiquement, d'un type numérique, entier sans doute non signé, composé de suffisamment de bits que pour pouvoir représenter "n'importe quelle adresse accessible sur le système cible").

    Or, en dehors du nom (qui n'est en définitive utile que pour l'humain) et de sa valeur, une variable est principalement identifiée par... son adresse mémoire.

    Et, quand on transmet un pointeur, on évite la copie de l'élément sous-jacent (de ce qui se trouve à l'adresse mémoire indiquée par le pointeur), mais on fait bel et bien un copie de... la variable qui est qualifiée de "pointeur" (pour etre précis : de la variable qui représente l'adresse mémoire).

    Du coup, il est tout à fait normal que, si tu prend l'adresse mémoire d'un pointeur représentant une même adresse mémoire dans deux fonctions différentes, tu obtiennes effectivement deux adresses différentes, vu qu'il s'agit bel et bien de deux variables différentes.
    Mais, généralement, on s'en fout pas mal, car, comme je l'ai dit, il s'agit de variables d'un type primitif entier, et donc, dont la création est très rapide et ne demande que très peu de ressources. Ce qui nous intéresse surtout, c'est que les deux variables nous indiquent la même adresse mémoire à laquelle aller chercher l'objet du type qui nous intéresse

    En rerprenant ton code, mais en supprimant la demande de l'adresse mémoire de ton pointeur, on se rend en effet compte que l'adresse vers laquelle pointent tes deux pointeurs est parfaitement identique, et c'est généralement ce qui compte ;p
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void truc()
    {
        int* hh = (int*)malloc(sizeof(int));
        *hh = 42;
        cout << "address : " << hh << endl;
        initializeTest(hh);
    }
     
    void initializeTest(int* h)
    {
        cout << "address : " << h << endl;
    }
    Mais, ceci dit, c'est la raison pour laquelle C fait une utilisation intensive des pointeurs de pointeurs ( Type **), de manière à nous permettre de disposer de... l'adresse mémoire à laquelle nous trouverons une information dont nous savons qu'il s'agit... de l'adresse mémoire à laquelle nous trouverons l'élément du type qui nous intéresse; par exemple, lorsqu'il s'agit de "réallouer" de la mémoire à un objet existant
    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

  3. #3
    Membre très actif Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Par défaut re
    Ok, merci pour tes expliquations mais du coup j'ai encore une question.
    Peux-tu m'aider pour ce qui suit ? (je suis un peu perdu)

    Voici mon vrai problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void truc() {
        int* hh = (int*)malloc(sizeof(int));
        int* dd;
        int* result = (int*)malloc(sizeof(int));
        *result = 99;
        *hh = 42;
        cudaMalloc((void**)&dd, 1*sizeof(int));
        cudaMemcpy(dd, hh, sizeof(int), cudaMemcpyHostToDevice);
        cudaMemcpy(result, dd, sizeof(int), cudaMemcpyDeviceToHost);
        cout << *hh << endl;
        cout << *result << endl;
    }
    Dans ce cas hh a bien été recopié dans result.

    Par contre ça ne fonctionne pas quand je met ce code dans une fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void truc() {
        int* hh = (int*)malloc(sizeof(int));
        int* dd;
        int* result = (int*)malloc(sizeof(int));
        *result = 99;
        *hh = 42;
     
        initializeTEST(hh, dd, result);
     
        cout << *hh << endl;
        cout << *result << endl;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void initializeTEST(int* h, int* d, int* res) {
        cudaMalloc((void**)&d, 1*sizeof(int));
        cudaMemcpy(d, h, sizeof(int), cudaMemcpyHostToDevice);
        cudaMemcpy(h, res, sizeof(int), cudaMemcpyDeviceToHost);
    }

  4. #4
    Membre très actif Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Par défaut
    HA HA !!

    Je viens de remarqué que j'ai inversé res et h.
    Bon bah c'est bon, ça devrait fonctionner correctement maintenant ^^

  5. #5
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Au passage, pourquoi faire des malloc() en C++ ?

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Pourquoi faire des malloc tout court, quand la variable est totalement interne à la fonction ?
    Ou alors c'est un programme dont le but est juste de générer une fuite mémoire ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Citation Envoyé par Matthieu76 Voir le message
    HA HA !!

    Je viens de remarqué que j'ai inversé res et h.
    Bon bah c'est bon, ça devrait fonctionner correctement maintenant ^^
    C'est la raison pour laquelle il est important de choisir des noms explicites pour les variables. La règle peut être adaptée en disant que, plus une variable "vit" longtemps, plus son nom doit être explicite : si tu n'a qu'un compteur qui ne sert que dans une boucle (ce que tout compteur devrait faire), tu peut te contenter de le nommer i ou cpt.

    Mais autrement, tu aurais sans doute remarqué bien plus vite le problème si tu avais utilise les termes host et destination (par exemple, car c'est ce que tu veux indiquer me semble-t-il) au lieu des nom h et dd, qui ne disent absolument rien de l'intérêt des variables
    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

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Pourquoi faire des malloc tout court, quand la variable est totalement interne à la fonction ?
    Ou alors c'est un programme dont le but est juste de générer une fuite mémoire ?
    il est possible de faire preuve de "pensée positive" et de se dire que Matthieu76 a présenté un code minimal compilant exposant le problème, mais basé sur un code bien plus complexe, pour lequel l'allocation dynamique peut s'avérer utile.

    D'autant plus qu'il est visiblement question de travailler avec Cuda, qui impose peut-être ses propres besoins
    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

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Tout à fait d'accord avec toi koala, mais ayant affaire à un débutant, il n'est pas rare - voire plutôt commun - de voir des malloc/new partout sans raison (parce que la fonction attend un pointeur et que c'est le seul/plus rapide moyen qu'ils connaissent pour en avoir un, l'utilisation de & n'est pas facile à appréhender, preuve avec le problème initial) donc le doute subsiste, et pas dans le sens où tu l'entends.
    Et quand bien même, un code minimal devrait inclure les free/delete et ça donne une meilleure impression de savoir ce que l'on écrit
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Nous sommes bien d'accord! C'est bien pour cela que j'ai parlé de pensée positive
    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

  11. #11
    Membre très actif Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Par défaut re
    Merci de vos réponses,
    Ce bout de code est juste là pour tester car vu que ça ne fonctionnait pas sur ma grosse fonction, j'ai tester avec du code plus simple pour plus facilement trouvé le problème, d'où le nom des variables
    Le but final étant de copier une structure dans la mémoire du GPU pour pouvoir accélérer mes calculs.

    D'ailleurs dans ma fonction d'initialisation je doit impérativement retourner le pointeur d, si je ne le récupère pas comme ça, il ne sera pas modifier. J'aurais surement dû faire un passage par référence de mon pointeur mais là c'est un peu compliqué pour moi. D’habitude je ne n'utilise que très rarement des pointeurs, j'utilise des vecteurs et je passe tout par référence.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int* initializeTEST(int* h, int* d)
    {
        cudaMalloc((void**)&d, 1*sizeof(int));
        cudaMemcpy(d, h, sizeof(int), cudaMemcpyHostToDevice);
        return d;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void returnTEST(int* d, int* res)
    {
        cudaMemcpy(res, d, sizeof(int), cudaMemcpyDeviceToHost);
    }

  12. #12
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Utiliser des vector au lieu de pointeur est une bonne pratique. Si t'oublie de le retourner, ou déplacer il libèrera la mémoire.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  13. #13
    Membre très actif Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Par défaut
    Merci pour l'astuce mais c'est déjà ce que je fais sur mon code CPU par contre sur mon code GPU je ne peux pas car je dois faire des vecteurs de vecteurs de tailles différentes et il est impossible de faire ça en cuda.
    Du coup j'ai quelques pointeurs et j'utilise des fonctions pour aller chercher la valeur que je souhaite à partir de mon pointeur.

    Ça me donne un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    inline
    void setWeightInHiddenLayers(network* nn, const int &l, const int &n, const int &w, const float &v)
    {
        nn->weightsInHiddenLayers[(l-1) * nn->numberOfNeuronInHiddenLayer * nn->numberOfNeuronInHiddenLayer +
                                 n * nn->numberOfNeuronInHiddenLayer + w] = v;
    }

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

Discussions similaires

  1. passer des pointeurs en VBA
    Par deubelte dans le forum C++
    Réponses: 2
    Dernier message: 01/10/2007, 17h48
  2. Comment passer des valeurs en arguments
    Par remi77 dans le forum Excel
    Réponses: 6
    Dernier message: 13/03/2007, 11h54
  3. Passer des arguments au binaire/exécutable
    Par Ljungberg dans le forum Autres éditeurs
    Réponses: 1
    Dernier message: 03/02/2006, 10h37
  4. Réponses: 6
    Dernier message: 21/12/2005, 18h52
  5. Comment passer des argument a un script php ?
    Par Florina dans le forum Linux
    Réponses: 2
    Dernier message: 11/12/2005, 14h38

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