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 :

affectation valeur à string


Sujet :

C++

  1. #1
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2016
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2016
    Messages : 278
    Par défaut affectation valeur à string
    Bonjour à tous,

    le code suivant ne fonctionne pas (ça plante):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    booleen    truc::machin(int sockfd, std::string *errMsg)
    {
        *errMsg = std::string("a");
     
        (suite correcte de la fonction)
    }
    Alors que la même chose mais sans partir d'une fonction, fonctionne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::string *err;
    *err = std::string("a");


    merci

  2. #2
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 750
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 750
    Par défaut
    Est-tu sérieux ?
    Sérieusement

    Au lieu d'utiliser 1 référence, tu veux la "faire à la C" sans initialiser ton pointeur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    booleen truc::machin(int sockfd, std::string& errMsg)
    {
        errMsg = "a";
     
    //  suite correcte de la fonction
    }

  3. #3
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2016
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2016
    Messages : 278
    Par défaut
    Merci pour ta réponse.
    Désolé, j'ai relu plusieurs fois, mais je ne comprends toujours pas.
    Quelle est la différence entre ce que j'ai fait et l'exemple donné ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int Ajout2(int * a){
    *a +=2;
     
    }
     
    int b = 3;
     
    Ajout2(&b);
    https://web.maths.unsw.edu.au/~lafay...p/cpppoint.htm

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    Tes 2 premiers exemples ont pour point commun de n'avoir aucun sens. Le premier est plutôt sympa, il plante. Le second est plus sournois, on ne sait pas ce qu'il fait vraiment. Le compilateur t'indique par des warnings beaucoup de cas anomaux, le second est flagrant et a dû t'être signalé.

    Pourquoi ça ne peut pas marcher? Parce qu'un pointeur, comme son nom l'indique, c'est fait pour pointer. On lui demande de pointer quelque part, et ensuite on s'en sert pour lire ou écrire l'endroit pointé. Mais on doit impérativement pointer sur quelque chose qui a bien le type pointé attendu.
    Dans tes exemples, le pointeur n'est pas initialisé. On ne doit pas tenter d'accéder à la zone pointée (en utilisant * ou -> ou []). Dans l'exemple foireux du cours, le code est correct, on a un pointeur qui pointe sur la variable b.

    Et comme l'a indiqué @foetus, c'est presque toujours une mauvaise idée d'utiliser des pointeurs. La preuve, on peut mal l'initialiser, ça fait n'importe quoi et dans le pire cas ça peut sembler marcher!

  5. #5
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2016
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2016
    Messages : 278
    Par défaut
    Dans l'exemple foireux du cours, le code est correct, on a un pointeur qui pointe sur la variable b.
    Il va de soi que dans mon code je passe une adresse string correctement déclarée à la fonction hein...
    Ou alors je ne pige rien.
    Sauf qu'à la différence de l'exemple du cours avec la variable b, le pointeur passe par plusieurs fonctions, dont une lambda.

  6. #6
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 750
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 750
    Par défaut
    Citation Envoyé par Chezkele Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int Ajout2(int * a){
    *a +=2;
     
    }
     
    int b = 3;
     
    Ajout2(&b);
    Tu débutes en C/ C++

    Ici ta variable locale b n'est pas 1 pointeur et tu passes son adresse &b - ici le passage sortie - entrée/ sortie peut être 1 référence.
    Les références, énorme ajout du C++: pas de syntaxe pointeur et pas de pointeur NULL/ "dangling pointer" - même si on peut y arriver.

    Citation Envoyé par Chezkele Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::string *err;
    *err = std::string("a");
    Ici ta variable locale err est 1 pointeur, et doit être
    • soit initialisée: err = new std::string("coucou"); /* test NULL et faire delete err */ attention malloc/ free c'est du C (notamment les constructeurs/ destructeurs ne sont pas appelés)
    • soit prendre l'adresse d'1 autre variable : std::string var="coucou"; err = &var;


    Va lire des cours en C++ , c'est la base de la base.

  7. #7
    CGi
    CGi est déconnecté
    Expert confirmé
    Avatar de CGi
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 061
    Détails du profil
    Informations personnelles :
    Localisation : France, Allier (Auvergne)

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 061
    Par défaut
    Citation Envoyé par Chezkele Voir le message
    le code suivant ne fonctionne pas (ça plante): ...
    Je ne vois pas d'erreur dans ton premier code (peut-être tu utilises pas correctement la fonction), mais bien sur il est préférable d'utiliser les références.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <iostream>
     
    void machin(std::string *errMsg)
    {
        *errMsg = std::string("abc");
    }
     
    int main()
    {
        std::string err;
        machin(&err);
        std::cout << err;
        return 0;
    }
    Par contre dans le second code, tu déréférence un pointeur non initialisé, et là tout peut ce produire, plantage ou autres...
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  8. #8
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2016
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2016
    Messages : 278
    Par défaut
    Merci CGi.
    Le code que tu présentes correspond effectivement à ce qui a été fait (pas par moi, je reprends le code de quelqu'un d'autre).
    A la différence près que l'adresse du string de départ voyage à travers plusieurs fonctions avant d'arriver à destination. Le problème est peut-être là.

  9. #9
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 750
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 750
    Par défaut
    Citation Envoyé par Chezkele Voir le message
    A la différence près que l'adresse du string de départ voyage à travers plusieurs fonctions avant d'arriver à destination. Le problème est peut-être là.
    Si tu connaissais la base de la base du C/ C++ (va voir 1 tutoriel ), tu serais que le passage de paramètres est par valeur.


    Citation Envoyé par CGi Voir le message
    Je ne vois pas d'erreur dans ton premier code (peut-être tu utilises pas correctement la fonction)
    1 code peut-être syntaxiquement valable, mais à l'exécution planté.
    D'ailleurs l'option -Wall du compilateur permet de détecter les variables non initialisées, peut-être le retour de variables locales, …

  10. #10
    CGi
    CGi est déconnecté
    Expert confirmé
    Avatar de CGi
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 061
    Détails du profil
    Informations personnelles :
    Localisation : France, Allier (Auvergne)

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 061
    Par défaut
    Citation Envoyé par foetus Voir le message
    D'ailleurs l'option -Wall du compilateur permet de détecter les variables non initialisées…
    Tu vois une variable non initialisée dans ce code ? Laquelle ?
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  11. #11
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 750
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 750
    Par défaut
    Citation Envoyé par CGi Voir le message
    Tu vois une variable non initialisée dans ce code ? Laquelle ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::string *err;
    *err = std::string("a");
    Parce qu'il faut comprendre , il a pris 1 fonction "C" (avec le pointeur) et comme il ne connait rien au C/ C++, le passage étant 1 pointeur (logique en C si tu veux modifier cette variable ou éviter 1 copie), alors il s'est dit "ma variable DOIT ÊTRE 1 pointeur"

  12. #12
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2016
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2016
    Messages : 278
    Par défaut
    Citation Envoyé par foetus
    Si tu connaissais la base de la base du C/ C++ (va voir 1 tutoriel ), tu serais que le passage de paramètres est par valeur.
    Je suis au courant.
    Je n'ai pas de grande prétention en C++ cependant, ni même en programmation en général, mais je m'amuse bien, j'aime bien chercher des solutions, et en l’occurrence je l'ai trouvée.

    En substance, le code ressemble à cela:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int Ajout2(int * b){
    *b +=2;
     
    }
     
    void fonctionBidule()
    {
    int b = 3;
     
    nomThread = obj.runThread(&jobs, &b);
    }
    Et entre fonctionBidule et l'appel d'Ajout2 il y a toute une cascade de fonctions qui se passent l'adresse de b.
    Sauf que, la fonction bidule arrive à sa fin, donc la variable b "meure". Et comme le thread, lui, survit, Ajout2 peut toujours être appelée alors que b est morte, et que donc utiliser son adresse n'est plus valide.
    J'ai réglé le problème en faisant de b un membre de l'objet dont fonctionBidule() est une méthode (je sais que vous n'aimez pas parler de "méthode" en C++, mais c'est quand même pratique parfois).
    Ce n'est peut-être pas très élégant de faire comme cela, mais je ne peux pas me permettre de faire x changement dans le code.

  13. #13
    CGi
    CGi est déconnecté
    Expert confirmé
    Avatar de CGi
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 061
    Détails du profil
    Informations personnelles :
    Localisation : France, Allier (Auvergne)

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 061
    Par défaut
    Citation Envoyé par foetus Voir le message
    Parce qu'il faut comprendre , il a pris 1 fonction "C" (avec le pointeur) et comme il ne connait rien au C/ C++, le passage étant 1 pointeur (logique en C si tu veux modifier cette variable ou éviter 1 copie), alors il s'est dit "ma variable DOIT ÊTRE 1 pointeur"
    Oui, mais comme tu parles de code que l'on ne vois pas et que tu supposes, on peine à te suivre.
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  14. #14
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 750
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 750
    Par défaut
    Citation Envoyé par CGi Voir le message
    Oui, mais comme tu parles de code que l'on ne vois pas et que tu supposes, on peine à te suivre.
    Critique également @Chezkele qui arrive avec 1 problème de pointeur et qu'en définitive c'est 1 problème de paramètre d'1 "worker thread".
    Moi je reprends son message original

  15. #15
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 446
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 446
    Par défaut
    alors que b est morte, et que donc utiliser son adresse n'est plus valide.
    @Chezkele, t'as de la chance que cela plante, dans beaucoup de configuration (compilateur, option de compilateur, système d'exploitation, etc...), c'est le genre de bug qui ne fait pas forcément planté le programme.
    Faut un peu plus de rigueur dans le conception, pour ne pas passer des jours sur des "heisenbug".

    Ta solution n'est pas "sale", si :
    Tu utilises des noms "correctes", avec une signification précise (parce que "b", c'est nimp)
    Que le l'objet ait une durée de vie supérieur au thread. Le plus simple, c'est de faire de "obj" (encore un nom qui sent pas la rose) un champ non partagé (l'ownership) de l'instance contenant la "méthode fonctionBidule" et faire en sorte que le destructeur de "obj" termine le thread si nécessaire.

    (je sais que vous n'aimez pas parler de "méthode" en C++, mais c'est quand même pratique parfois).
    Si c'est si "pratique", explique-nous ta différence entre méthode et fonction, STP ?

    Mais une solution peut-être plus safe et flexible, c'est de faire de "b" un champs de "jobs", non ?

    Encore un "xy problem".

  16. #16
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    750
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 750
    Par défaut
    J'ai l'impression que b n'est pas utilisée en dehors de la fonction. Dans ce cas le plus simple est de passer par une lambda pour définir les variables dans la pile du nouveau thread: runThread([]{ int b; something(b); })

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

Discussions similaires

  1. récupérer une valeur String, est-ce correct.
    Par LESOLEIL dans le forum Langage
    Réponses: 2
    Dernier message: 06/04/2006, 10h56
  2. [VBA-E]Affecter valeurs noms de fichier d'un répertoire
    Par zzman dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 20/03/2006, 00h28
  3. [Affectation] Valeurs pré-définies
    Par Mister Nono dans le forum Langage
    Réponses: 6
    Dernier message: 23/01/2006, 17h03
  4. Affecter valeur par defaut si champ vide
    Par uloaccess dans le forum Access
    Réponses: 5
    Dernier message: 09/01/2006, 17h12
  5. FORMS : affecter valeur a champ date
    Par sdiack dans le forum Oracle
    Réponses: 1
    Dernier message: 08/12/2005, 23h37

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