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 :

Mes pointeurs se font �craser ???


Sujet :

C++

  1. #1
    Membre confirm�
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    95
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 95
    Par d�faut Mes pointeurs se font �craser ???
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
     
    Noms * liste_personne[32];
    Vaut-il mieux faire :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class Noms
    {
         char * m_nom[32];
         ...
         void SetNom(int i, char * nom)
         {
               m_nom[i] = (char*)malloc(_tcslen(nom) * sizeof(char));
               sprintf(m_nom[i], nom);
         }
    };
    Ou plut�t :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class Noms
    {
         char * m_nom[32];
         ...
         void SetNom(int i, char * nom)
         {
               m_nom[i] = nom;
         }
    };
    Dans la premi�re solution, j'ai des raisons de penser qu'au fur et � mesure que l'on cr�� les personnes et que l'on rempli les noms dynamiquement, il est possible que l'allocation empi�te sur les pointeurs (c possible �a ?). C'est la seule explication que j'ai. Ainsi, lorsque je fait:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    liste_personne[0] = new Noms();
    liste_personne[0]->SetNom(0, "toto");
    liste_personne[0]->SetNom(1, "tata");
    ...
     
    liste_personne[1] = new Noms();
    liste_personne[1]->SetNom(0, "titi");
    liste_personne[1]->SetNom(1, "tutu");
    ...
    L'appel des m�thodes SetNom() semble allouer de la m�moire sur laquelle est le pointeur vers liste_personne suivant (liste_personne[1] ici puis les autres...), et donc j'obtiens un zoli plantage.

    Dans la 2�me solution (classe), faire pointer mes pointeurs directement vers les chaines pass�es en param�tres ne semble pas tr�s "propres" puisque qu'il s'agit (a priori) de chaines de caract�res temporaires (je pense) qui seraient donc effac�es si la m�moire le decidait.

    Que faire ?

  2. #2
    jmv
    jmv est d�connect�
    Membre chevronn� Avatar de jmv
    Profil pro
    Enseignant
    Inscrit en
    Mai 2004
    Messages
    395
    D�tails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activit� : Enseignant

    Informations forums :
    Inscription : Mai 2004
    Messages : 395
    Par d�faut
    vu l'heure tardive, j'ai du mal avec les pointeurs
    Citation Envoy� par norwy
    Que faire ?
    utiliser les string et vector de la STL

  3. #3
    Membre confirm�
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    95
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 95
    Par d�faut
    On ne peut pas toujours passer par une autre solution et je trouve que j'�voluerais positivement en sachant au moins pourquoi la 1�re solution ne marche effectivement pas (en repassant � la 2�me �a marche � nouveau). Contourner les probl�mes ne dure qu'un temps...

    J'explique le fond du probl�me, ce programme tourne aussi bien sur PC que sur PocketPC (d'o� entre autre ma r�ticence � le contourner + la raison invoqu�e pr�c�demment) o� le type est en fait TCHAR et non pas char (on est en unicode), mais le principe est strictement le m�me (toutes les fonctions appel�es ont leur �quivalent unicode support� par les 2 plateformes).

    La 1�re version marche dans la version PC mais pas dans la version PocketPC. Pourquoi ? Est-il possible que le peu de RAM disponible conduit � une probabilit� plus grande que l'espace entre les pointeurs � la cr�ation du tableau de Noms* (liste_personne) soit si petit que l'allocation dynamique puisse d�border sur les pointeurs suivants, d'o� plantage ?

    liste_personne[1] n'existerait plus alors � la suite des allocations g�n�r�es par l'appel de la m�thode SetNom() depuis liste_personne[0].

    J'insiste sur le fait que ce probl�me pourrait aussi bien �tre valide sur PC.
    Le probl�me ne se verrait pas de suite sur PC car il doit y avoir une methode qui pr�voit un espace cons�quent entre les pointeurs suffisant pour palier � ce probl�me lorsque l'allocation est petite...


    Ce que je voudrais savoir, c'est si cette explication est une pure invention de ma part (plausible puisque le probl�me s'est d�clar� vers 2h du mat et qu'entre temps je n'ai pas beaucoup dormi ), ou si j'ai bon...


    : : :

    AVE

  4. #4
    Membre chevronn�
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Par d�faut
    Je ne vois pas en quoi le fait que le prog doivent tourner sur pocket PC soit un frein � l'utilisation de la biblioth�que standard. Ca �viterais au moins d'utiliser des fonctions non standard type stprintf ou autre. Mais bon, ce n'est pas la question.

    Je comprend mal ce que mod�lise la classe Noms. Est-ce un ensemble de noms, comme le sugg�re le pluriel ? Ou est-ce un nom unique comme le sugg�re la d�claration 'Noms * liste_personnes[32]' ?
    De l'impl�mentation, j'en d�duit que Noms est une liste de chaine de caract�res. Donc une liste de personnes est un tableau o� chaque �l�ment est lui m�me un tableau de 32 chaines de caract�re. Etrange, mais passons.

    Ce qui est incompr�hensible, c'est comment ton premier exemple puisse compiler.
    Dans ta m�thode 'SetNom' tu affectes � 'nom' un pointeur sur une chaine de caract�re.
    Ceci est impossible. La variable d'instance nom est un pointeur sur un tableau de cha�nes de caract�res (char * [32]) et tu lui affecte un pointeur sur une chaine de caract�re (char*).
    C'est comme dire qu'un entier et un tableau d'entier sont la m�me chose.
    Si ton compilo accepte une telle chose, change le . Sinon, poste un code qui compile si tu souhaite avoir une meilleure r�ponse.

    Autre chose, conventionellement les noms de variables pr�fix�es par un underscore ('_') sont r�serv�s pour les variables d'instances. La convention que tu emploies, c-�-d utiliser ces noms pour les param�tres de fonction est assez emb�tante � lire.

  5. #5
    Membre confirm�
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    95
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 95
    Par d�faut
    Oki, je viens de r�editer tout �a... effectivement, quelques erreurs se sont gliss�es dans mon code (qui n'est qu'une repr�sentation de mon code r�el qui lui se compile sans erreurs de ce genre). voil�...

    Par ailleurs, chaque case du tableau liste_personne repr�sente une liste de personnes donc de noms chacun g�r�e par la classe Noms.

    liste_personnes[0] est la 1�re liste de 32 noms...
    liste_personnes[1] est la 2�me liste de 32 noms...
    et ainsi de suite...

    Bon ceci �tant r�solu, revenons � nos moutons... est-ce possible ou non?

  6. #6
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Eh bien moi, je te conseillerais la premi�re m�thode (faire une copie)

    Mais pour l'instant, je ne sais pas trop si les erreurs que je vois dans ton code sont dues � la copie ou sont aussi dans ton code originel. Toujours est-il que tu n'alloues pas de place pour le z�ro terminal lors de ta copie.
    Pour �viter des erreurs comme �a, je te conseillerais d'utiliser la fonction _tcsdup()...

    Et bien sur, les pr�cautions d'usage: Initialisation des pointeurs � NULL dans le constructeur, lib�ration de la pr�c�dente zone m�moire dans le SetNom(), etc.
    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 chevronn�
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Par d�faut
    Si la question est 'l'allocation d'une cha�ne de caract�re peut-elle �craser un bloc m�moire utilis� ?' la r�ponse est non. Si l'allocation dynamique n'est pas possible parce qu'il n'y a plus d'espace disponible, malloc retourne un pointeur nul et n'�crase rien.

  8. #8
    Membre confirm�
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    95
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 95
    Par d�faut
    ok, alors �a peut �tre une erreur due � ce caract�re de fin '\0'

    Question tr�s b�te, comment je lib�re la pr�c�dente m�moire ? avec un free ? Il n'est pas sens� rendre inutilisable le pointeur par la suite ?

  9. #9
    Membre confirm�
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    95
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 95
    Par d�faut
    ok, alors �a peut �tre une erreur due � ce caract�re de fin '\0'

    Question tr�s b�te, comment je lib�re la pr�c�dente m�moire ? avec un free ? Il n'est pas sens� rendre inutilisable le pointeur par la suite ?

  10. #10
    Membre confirm�
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    95
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 95
    Par d�faut
    ok, alors �a peut �tre une erreur due � ce caract�re de fin '\0'

    Question tr�s b�te, comment je lib�re la pr�c�dente m�moire ? avec un free ? Il n'est pas sens� rendre inutilisable le pointeur par la suite ?

  11. #11
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    je ne dis pas lib�rer la m�moire pass�e en param�tre: je parle de lib�rer ce qui y avait avant � cette case-la quand tu doit y mettre une nouvelle cha�ne

    bref, �viter une fuite de m�moire quand je fais:
    SetNom(1, "abc");
    SetNom(1, "def");

    Au fait, tu devrais d�clarer SetNom(int i, const char *nom) puisque tu fais une copie: la cha�ne pass�e en param�tre ne sera jamais modifi�e par la fonction...
    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.

  12. #12
    Membre confirm�
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    95
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 95
    Par d�faut
    C'est bien ce que j'avais compris en parlant de pr�c�dente m�moire et ma question est si je fais �a �a va me poser des probl�mes non ?

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
     
         void SetNom(int i, const char * nom) 
         {
               free(m_nom[i]);
    //         m_nom[i] = NULL;
               m_nom[i] = _tcsdup(nom);
         }

  13. #13
    Expert confirm�
    Avatar de Luc Hermitte
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2003
    Messages
    5 296
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : A�ronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Ao�t 2003
    Messages : 5 296
    Par d�faut
    1- oubli de prise en compte du 0 terminal -- ce qui est capital!!
    2- partir en exception si le malloc ne peut allouer
    3- new[] est bien plus simple � utiliser que malloc (pas de sizeof redondant), delete[] qui fonctionne sur les pointeurs nuls, new qui l�ve des exception en cas d'impossibilit� d'allocation
    4- const char* pour les param�tres entrants non modifiales
    5- utiliser une classe RAII-sante. En supposant que std::string n'est pas support� sur ta plateforme, une classe raii-sante de chaines constantes avec comptage de r�f�rence est vite �crite. En plus, cela se valide tr�s bien avec des test unitaires, apr�s plus qu'� utiliser.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne r�ponds � aucune question technique par le biais de ce m�dia. Et de toutes fa�ons, ma BAL sur dvpz est pleine...

  14. #14
    Membre confirm�
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    95
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 95
    Par d�faut
    ben, c'est � dire que le _tcsdup (strdup pour les TCHAR) a bien arrang� les choses puisqu'il fait lui m�me ce malloc avec le 0 terminal.

    Ce que j'ai besoin maintenant de savoir c'est comment palier � la fuite m�moire dont parle M�dinoc. (le free rend bien inutilisable le pointeur).

    Et accessoirement, quelle la meilleure fa�on de faire un �quivalent � strndup qui duplique n caract�res de ma chaine ?

  15. #15
    R�dacteur/Mod�rateur
    Avatar de JolyLoic
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    5 463
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 51
    Localisation : France, Yvelines (�le de France)

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

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 5 463
    Par d�faut
    Citation Envoy� par norwy
    Ce que j'ai besoin maintenant de savoir c'est comment palier � la fuite m�moire dont parle M�dinoc. (le free rend bien inutilisable le pointeur).
    En faisant une classe string, comme te l'as d�j� conseill� Luc...


    Citation Envoy� par norwy
    Et accessoirement, quelle la meilleure fa�on de faire un �quivalent � strndup qui duplique n caract�res de ma chaine ?
    En mettant un op�rateur = dans ta classe string.
    Ma session aux Microsoft TechDays 2013 : D�velopper en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage � la d�couverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'h�sitez pas � me contacter.

  16. #16
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Citation Envoy� par norwy
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
     
         void SetNom(int i, const char * nom)
         {
               free(m_nom[i]);
    //         m_nom[i] = NULL;
               m_nom[i] = _tcsdup(nom);
         }
    Ben c'est parfait, comme �a! Plus de fuite de m�moire...
    Et si les pointeurs sont bien initialis�s � NULL dans le constructeur, ici on tombera sur un free(NULL) qui, selon la norme, n'est pas dangereux.

    Citation Envoy� par JolyLoic
    Citation Envoy� par norwy
    Et accessoirement, quelle la meilleure fa�on de faire un �quivalent � strndup qui duplique n caract�res de ma chaine ?
    En mettant un op�rateur = dans ta classe string.
    Le rapport???
    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.

  17. #17
    Membre chevronn�
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Par d�faut
    Y'a m�me pas besoin de recr�er une classe chaine. Le mieux si le but est de manipuler des TCHAR (enfin un type de caract�re quel qu'il soit), c'est d'utiliser une cha�ne standard de TCHAR : typedef basic_string<TCHAR> mystring

    D'ailleurs �a ne m'�tonnerais pas qu'un TCHAR soit exactement la m�me chose qu'un wchar_t (� la red�finition microsoftienne pr�s), et donc que l'on puisse directement utiliser le typedef de la librairie standard pour les cha�ne en UNICODE : wstring

    Ca permettra de supprimer tout ce fatras de malloc, free, strcopy et autre archa�smes h�rit�s du C qui rendent les applis inmaintenables et incompr�hensibles.
    Du coup, tout les algos de manips de cha�nes seront accessible et notamment la duplication de tout ou une partie de la cha�ne.
    Accessoirement, plus aucune gestion de m�moire ne sera n�cessaire.

  18. #18
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Un TCHAR, si UNICODE (ou _UNICODE : on voit les deux) est d�fini (dans les options ou par un #define), c'est un wchar_t
    si UNICODE n'est pas d�fini, c'est un char.


    Le probl�me majeur des wchar_t sous Dev-C++, c'est que wcout (et sans doute les autres flux "standard" unicode) ne marche pas. Quand j'ai demand� ici comment le faire marcher, on m'a r�pondu qu'on n'avait pas encore r�ussi...
    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.

  19. #19
    Membre chevronn�
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Par d�faut
    Puisque l'OP veut de l'unicode, alors wstring est ce qu'il faut.
    Il suffit de r�cup�rer une fonction de transcodage pour l'affichage

Discussions similaires

  1. [JMeter] Mes sc�narios ne font rien mais Jmeter dit que tout va bien :(
    Par kahya dans le forum Tests et Performance
    R�ponses: 1
    Dernier message: 27/07/2010, 14h32
  2. R�ponses: 1
    Dernier message: 27/10/2009, 19h56
  3. [d�butant] Mes controles n'ent font qu'� leur t�te!
    Par Alouka dans le forum Visual C++
    R�ponses: 3
    Dernier message: 25/10/2006, 10h17
  4. R�ponses: 7
    Dernier message: 02/12/2005, 13h02
  5. mes pointeurs se "croisent"
    Par salseropom dans le forum C
    R�ponses: 16
    Dernier message: 16/11/2005, 09h22

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