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 :

wstring, c_str() et size


Sujet :

C++

  1. #1
    Membre actif
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2006
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2006
    Messages : 245
    Points : 232
    Points
    232
    Par défaut wstring, c_str() et size
    Bonjour à tous,

    Voici un petit casse-tête dont je ne me sors pas.
    Je tente de récupérer un wstring dans un wchar, et le wchar résultant n'est pas conforme, pourtant la taille semble correcte.
    Je m'explique : je m'attend à recevoir la chaine "Pouet", or je ne reçois que "P".
    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
     
    WCHAR wcTemp[STRING_MAXIMAL_SIZE];
    std::wstring Name; // Ceci est rempli ailleurs, et vaut "Pouet"
    // Test 1
    swprintf_s(wcTemp, STRING_MAXIMAL_SIZE, L"%s", Name.c_str());
    // Test 2
    wcscpy_s(wcTemp, STRING_MAXIMAL_SIZE, Name.c_str());
     
    if (wcslen(wcTemp) < 3)
    {
    	WCHAR Plop[10];
    	swprintf_s(Plop, 10, L"%d", my_data->my_parameter.Name.size());
    	MessageBox(hwnd, wcTemp, Plop, MB_OK);
    }
    // Même sur le test 3:
    if (wcslen(wcTemp) < 3)
    {
    	MessageBox(hwnd, wcTemp, my_data->my_parameter.Name.c_str(), MB_OK);
    }
    Et là, le miracle arrive :
    Tests 1 et 2, la message box m'affiche, en titre, 5, et dans le texte : "P"
    Test 3, la messagebox m'affiche, en titre, "P", et dans le texte : "P".
    Je ne comprend pas.

    Petites précisions:
    1°) Ceci est fait sous WinCE6.0
    2°) Ces modifications sont faites dans des threads gérants des lignes (un thread par ligne), et cela n'arrive très généralement qu'au bout de 146 lignes... Toutes les autres lignes sont bonnes !
    3°) Lorsque j'ai déjà affiché une première fois, pas de problème lors du second affichage.

    Si vous avez une idée, ou besoin de précisions, n'hésitez pas

    Merci
    Les gens croient qu'il est agréable d'être un super-génie, mais s'ils savaient à quel point il est difficile d'être entouré de super-crétins !
    Calvin dans Calvin et Hobbes (Bill Watterson)

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Je ne connais pas trop les Windows Embedded, mais essaie en appelant explicitement MessageBoxW().
    Edit: Peut pas être ça, car ce serait systématique.

    Vérifie qu'il n'y a aucun risque qu'un autre thread modifie l'une de tes variables.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre actif
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2006
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2006
    Messages : 245
    Points : 232
    Points
    232
    Par défaut
    Salut Médinoc,

    Merci pour ta réponse.
    Pour le coup du MessageBoxW, en fait, c'est bien celle-là qui est appelée, car le MessageBox est un #define qui renvoie vers MessageBoxW (Unicode)

    Je ne vois vraiment aucun thread susceptible de modifier cette donnée.

    Je connais la string qui doit s'afficher. Que je mesure la taille avant ou après la récupération de la string par un swprintf_s ou par un wcscpy_s, la taille de la string est bonne, le texte est faux (un seul, zéro ou plusieurs caractères).
    Au deuxième passage, je n'ai pas de problème.

    Je ne vois vraiment pas du tout d'où peux venir le problème.

    Le plus dingue, c'est que si, avant d'afficher toutes les lignes (149), j'affiche tous les textes dans une grande MessageBox, les lignes sont TOUTES correctes.
    Si je force un nouvel affichage, les lignes sont TOUTES bonnes.
    Sans déconner, j'en peux plus
    Les gens croient qu'il est agréable d'être un super-génie, mais s'ils savaient à quel point il est difficile d'être entouré de super-crétins !
    Calvin dans Calvin et Hobbes (Bill Watterson)

  4. #4
    Membre actif
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2006
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2006
    Messages : 245
    Points : 232
    Points
    232
    Par défaut Résolu !
    Salut,

    Un petit mot pour dire que le problème est résolu, et évidemment, l'explication (en tout cas, celle que je peux en faire).
    Et le problème ne vient pas de là où je l'attendais, comme d'habitude.

    Le problème n'apparait que sur Windows CE 6.0 (128MO de RAM), non pas sur mon PC (Windows 7 32 bits avec tout plein de RAM). Ensuite, il n'apparait que lors du premier affichage : lors des suivants, tout se passe correctement.
    Cela ressemble donc à un problème de gestion de la mémoire : mes nombreux paramètres sont stockés dans un "std::vector", et je suppose que la taille réservée lors du premier passage n'est pas bonne, qu'il faut ajouter de la place, puisqu'au deuxième passage, la place est déjà réservée, et tout se passe correctement.
    J'ai donc réservé (avec la fonction tout bêtement "reserve") par défaut la taille maximale possible des paramètres (qu'heureusement je connais), et tout se passe bien depuis, le problème ne se répète plus.

    J'espère avoir été clair, et avoir résolu le problème (et non caché en pensant avoir compris).

    À plus tard

    PS : Windaube CE, quelle dows
    Les gens croient qu'il est agréable d'être un super-génie, mais s'ils savaient à quel point il est difficile d'être entouré de super-crétins !
    Calvin dans Calvin et Hobbes (Bill Watterson)

  5. #5
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Citation Envoyé par jacklafrip
    mes nombreux paramètres sont stockés dans un "std::vector", et je suppose que la taille réservée lors du premier passage n'est pas bonne, qu'il faut ajouter de la place, puisqu'au deuxième passage, la place est déjà réservée, et tout se passe correctement.
    J'ai donc réservé (avec la fonction tout bêtement "reserve") par défaut la taille maximale possible des paramètres (qu'heureusement je connais), et tout se passe bien depuis, le problème ne se répète plus.
    Hmm cette solution "solution" laisse fortement penser que l'erreur vient plutôt d'une mauvaise utilisation de std::vector qu'autre chose.

    Accuser wince est un peu ridicule ici vu que le code de la bibliothèque standard est identique entre windows desktop et wince pour une même version de visual studio. Il est plus raisonnable de penser qu'une erreur dans ton code déclenchait un comportement indéterminé, ce qui peut effectivement donner des résultats différents de système à système.

    De tête je dirais qu'il y a deux scénarios assez fréquent dans lequel un reserve peut soit masquer soit corriger un problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    std::vector<std::wstring> v;
    v[0] = "param0";
    v[1] = "param1";
    v[2] = "param2";
    Ce genre de code provoque un comportement indéterminé (souvent un crash)
    Alors que l'utilisation correcte est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    v.push_back("param0");
    v.push_back("param1");
    v.push_back("param2");
    Le truc, dans le premier c'est que si l'on rajoute un reserve après la déclaration de v, le code est toujours faux, mais il y a plus de chance que le comportement indéterminé soit plus subtil et ne crash pas systématiquement. C'est un cas où ajouter un reserve masque le problème.

    De manière générale lorsqu'on l'on fait v[i] = qqchose, il faut bien s'assurer que v.size() > i

    Deuxième cas, où cette fois le reserve() est justifié et corrige le problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    std::vector<std::wstring> v;
    v.push_back("param0");
    std::wstring* ptr0 = &v[0]; 
    foo(ptr0);
    v.push_back("param1");
    v.push_back("param2");
    v.push_back("param3");
    v.push_back("param4");
    foo(ptr0); // erreur ici !!
    ptr0 est probablement invalide maintenant car il est très probable que le vecteur suite à un push_back pour s'agrandir a du réallouer son buffer interne, donc le pointeur pointe maintenant sur une zone de mémoire invalide.

    Dans ce cas, faire un v2.reserve(TAILLE_MAX) est une bonne solution et corrige effectivement le problème car on a alors la garantit après le reserve que le buffer interne est suffisament grand pour qu'aucune réallocation ne soit nécessaire pendant l'utilisation du vector, donc tout pointeur pointant dans le vecteur restera valide.

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Je conseillerais plutôt resize() que reserve() selon le cas, car sinon j'ai l'impression qu'il est possible d'appeler operator=() sur un objet non construit (mais je peux me tromper).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre averti
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Points : 439
    Points
    439
    Par défaut
    Pour autant que je sache, le message de Arzar est parfait...

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

Discussions similaires

  1. [Oracle 8i][Internet] Shared Pool Size
    Par dupin40 dans le forum Administration
    Réponses: 39
    Dernier message: 04/11/2004, 12h39
  2. [font.size] Comment descendre en dessous de 8 ?
    Par Dry dans le forum Composants VCL
    Réponses: 3
    Dernier message: 23/04/2004, 16h01
  3. pb de select avec size avec choix multiple
    Par La_picolle dans le forum ASP
    Réponses: 10
    Dernier message: 28/08/2003, 15h21
  4. Erreur "size array"
    Par boobob dans le forum C
    Réponses: 3
    Dernier message: 06/08/2003, 10h18

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