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 :

Assigner char * à un attribut fait planter le programme


Sujet :

C++

Vue hybride

Lynix Assigner char * à un attribut... 18/10/2009, 00h49
JulienDuSud stp, utilises std::string. 18/10/2009, 04h25
Invité c'est lequel qui plante ? 18/10/2009, 10h43
Lynix Non, c'est fait exprès que... 18/10/2009, 10h43
Invité c'est peut etre le code qui... 18/10/2009, 11h53
Lynix Avec deux const char *... 18/10/2009, 13h42
JolyLoic Je ne crois pas que ce soit... 19/10/2009, 12h04
Invité http://en.wikipedia.org/wiki/S... 19/10/2009, 12h42
jabbounet dans le code que tu met je... 19/10/2009, 14h17
Lynix Non, le +1 est déjà pris en... 19/10/2009, 18h06
jabbounet problème de version de... 19/10/2009, 18h15
peufeu Ton digest, c'est une chaîne... 24/10/2009, 20h38
Lynix De l'hexadécimal, mais le... 24/10/2009, 23h58
Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Février 2009
    Messages
    141
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 141
    Par défaut Assigner char * à un attribut fait planter le programme
    Bonjour,
    Dans le cadre d'une classe résultant d'un Hash (SHA256, MD5, etc) possédant trois informations (Nom du hash, Hash, Longueur du hash), j'ai un problème quand j'assigne un pointeur à un de mes attribut.

    Je n'ai jamais vraiment eu de problème avec ma classe, mais j'ai réparé le système qui hachait et depuis que lui fonctionne, la classe ne fonctionne plus.

    Le plus étrange est que cela vient juste de l'affectation de "new char[taille]" à un attribut m_hashName, l'allocation du new char[taille] ou simplement le calcul de la taille ne cause pas le problème.

    Par exemple je peux allouer une variable exactement comme pour l'allocation originale, et le programme crash si je l'affecte à l'attribut.

    Exemples :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    m_attribut = new char[taille]; // Plante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    char *test = new char[taille]; // Ok, pas de souci
    m_attribut = test; // Plante
    Voici le code complet de la classe pour ceux qui veulent :
    HashString.h:
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    #ifndef UU_HASHSTRING_H_INCLUDED
    #define UU_HASHSTRING_H_INCLUDED
     
    #include <cstring>
    #include <iostream>
     
    namespace Ungine
    {
    	namespace Utils
    	{
    		class HashString
    		{
    			public:
    				HashString();
    				HashString(const char *hashName, const char *digest);
    				HashString(const HashString& hs);
    				~HashString();
     
    				bool IsValid() const;
     
    				const char *GetDigest() const;
    				const char *GetHashName() const;
    				unsigned int GetLength() const;
     
    				HashString& operator=(const HashString &hash);
    				bool operator==(const HashString &hash) const;
    				bool operator!=(const HashString &hash) const;
     
    			private:
    				char *m_digest;
    				char *m_hashName;
    				unsigned int m_length;
    		};
     
    		std::ostream& operator<<(std::ostream &out, HashString &string);
    	}
    }
    #endif // UU_HASHSTRING_H_INCLUDED
    HashString.cpp:
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
     
    #include "HashString.h"
     
    namespace Ungine
    {
    	namespace Utils
    	{
    		HashString::HashString() :
    		m_digest(0),
    		m_hashName(0),
    		m_length(0)
    		{
    		}
     
    		HashString::HashString(const char *hashName, const char *digest)
    		{
    			m_hashName = new char[strlen(hashName)+1];
    			strcpy(m_hashName, hashName);
    			m_digest = new char[strlen(digest)+1];
    			strcpy(m_digest, digest);
    			m_length = strlen(digest);
    		}
     
    		HashString::HashString(const HashString& hs)
    		{
    			m_hashName = new char[strlen(hs.m_hashName)+1];
    			strcpy(m_hashName, hs.m_hashName);
    			m_digest = new char[strlen(hs.m_digest)+1];
    			strcpy(m_digest, hs.m_digest);
    			m_length = strlen(m_digest);
    		}
     
    		bool HashString::IsValid() const
    		{
    			return m_length > 0;
    		}
     
    		HashString::~HashString()
    		{
    			delete[] m_digest;
    			delete[] m_hashName;
    		}
     
    		const char *HashString::GetDigest() const
    		{
    			return m_digest;
    		}
     
    		const char *HashString::GetHashName() const
    		{
    			return m_hashName;
    		}
     
    		unsigned int HashString::GetLength() const
    		{
    			return m_length;
    		}
     
    		HashString& HashString::operator=(const HashString &hash)
    		{
    			delete[] m_hashName;
    			delete[] m_digest;
    			m_hashName = new char[strlen(hash.m_hashName)+1];
    			strcpy(m_hashName, hash.m_hashName);
    			m_digest = new char[strlen(hash.m_digest)+1];
    			strcpy(m_digest, hash.m_digest);
    			m_length = strlen(hash.m_digest);
    			return *this;
    		}
     
    		bool HashString::operator==(const HashString &hash) const
    		{
    			return strcmp(m_digest, hash.m_digest) && strcmp(m_hashName, hash.m_hashName);
    		}
     
    		bool HashString::operator!=(const HashString &hash) const
    		{
    			return !strcmp(m_digest, hash.m_digest) || !strcmp(m_hashName, hash.m_hashName);
    		}
    	}
    }
     
    std::ostream& operator<<(std::ostream& out, Ungine::Utils::HashString& string)
    {
    	out << string.GetDigest();
    	return out;
    }
    Qu'est-ce que j'ai fais de mal?

    Je précise que l'erreur intervient dans le constructeur "HashString::HashString(const char *hashName, const char *digest)"

    Merci d'avance

  2. #2
    Membre chevronné
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Par défaut
    stp, utilises std::string.

  3. #3
    screetch
    Invité(e)
    Par défaut
    c'est lequel qui plante ?

  4. #4
    Membre très actif
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Février 2009
    Messages
    141
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 141
    Par défaut
    Non, c'est fait exprès que j'utilise les chaines de caractère du C, parce que mon programme utilise beaucoup de classe de chaine de caractère différentes.

    En attendant que la classe de chaine de caractère principale soit écrite, j'utilise des C-string, mais ce qui m'inquiète c'est que je risque de rencontrer ce problème avec cette classe aussi.

    Ah je précise que l'erreur intervient dans le constructeur qui reçoit deux const char*

  5. #5
    screetch
    Invité(e)
    Par défaut
    c'est peut etre le code qui appelle cette fonction qui est mauvais. Comment tu appelles ce constructeur ?

  6. #6
    Membre très actif
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Février 2009
    Messages
    141
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 141
    Par défaut
    Avec deux const char * valides (Peuvent être affichés, mesurés, copiés sans problème)

    De toute façon ça plante avant même d'utiliser les arguments

    EDIT : je viens de tester la classe dans un main, elle fonctionne sans problème

    Voila la méthode où elle est crée et où ça plante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    			HashString SHA256::End()
    			{
    				char buffer[UU_HASH_SHA256_DIGEST_LENGTH];
    				SHA256_Internal_End(buffer);
     
    				char *finalHash = new char[UU_HASH_SHA256_DIGEST_STRING_LENGTH];
    				strcpy(finalHash, buffer);
     
    				HashString final(UU_HASH_SHA256_NAME, finalHash);
     
    				delete[] finalHash;
    				return final;
    			}
    EDIT2 : Même en créant un HashString vide (Constructeur par défaut), ça plante sur l'initialisation de m_hashName :/

    L'erreur semble venir de ce bout de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    				char buffer[UU_HASH_SHA256_DIGEST_LENGTH];
    				SHA256_Internal_End(buffer);
    Je ne comprend vraiment pas...

    EDIT 3 :
    J'ai encore modifié le code pour créer directement un pointeur
    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
    			HashString SHA256::End()
    			{
    				char *buffer = new char[UU_HASH_SHA256_DIGEST_LENGTH];
    				SHA256_Internal_End(buffer);
     
    				std::cout << buffer << std::endl;
     
    				//char *finalHash = new char[UU_HASH_SHA256_DIGEST_STRING_LENGTH];
    				//strcpy(finalHash, buffer);
     
    				HashString final;
     
    				//delete[] finalHash;
    				return final;
    			}
    Ce code fonctionne avec le debugger, mais plante en renvoyant une erreur quand je le lance normalement (Process terminated with status -1073741819 (0 minutes, 2 seconds)

    Pourquoi est-ce que le code fonctionne avec le debugger mais pas normalement?

  7. #7
    screetch
    Invité(e)
    Par défaut
    strlen(0) plante je crois, tu devrais faire attention a ca dans ta classe.
    un HashString initialisé par défaut met ses chamts chaine a 0, puis une copie va claculer strlen(0) ce qui peut faire crasher.

  8. #8
    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 : 50
    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 Lynix Voir le message
    Non, c'est fait exprès que j'utilise les chaines de caractère du C, parce que mon programme utilise beaucoup de classe de chaine de caractère différentes.

    En attendant que la classe de chaine de caractère principale soit écrite, j'utilise des C-string, mais ce qui m'inquiète c'est que je risque de rencontrer ce problème avec cette classe aussi.
    Je ne crois pas que ce soit une bonne idée.

    En attendant que la classe chaîne de caractère principale soit écrite (mais pourquoi en écrire une ? std::string pose problème ?), utilise quand même une classe qui gère l'allocation, peu importe laquelle, ça évitera les problèmes liés à l'écriture d'une version, même temporaire, à base de C-string, et le basculement sera probablement plus simple.
    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.

  9. #9
    screetch
    Invité(e)
    Par défaut
    [ame="http://en.wikipedia.org/wiki/Shotgun_debugging"]http://en.wikipedia.org/wiki/Shotgun_debugging[/ame]
    je ne suis pas fan de conseiller de changer de techno "en esperant que le probleme va disparaitre".

  10. #10
    Membre chevronné
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Par défaut
    Citation Envoyé par screetch Voir le message
    http://en.wikipedia.org/wiki/Shotgun_debugging
    je ne suis pas fan de conseiller de changer de techno "en esperant que le probleme va disparaitre".
    Non mais là c'est pas du shotgun debugging, c'est simplement remplacer tout le code buggé par un code robuste, testé, de haut niveau.

    Rien qu'en apercevant le code, je suis sûr et certain que c'est un problème d'allocation quelque part ou de temporaire, bref un truc avec la mémoire quoi.

  11. #11
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    dans le code que tu met je vois
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char *buffer = new char[UU_HASH_SHA256_DIGEST_LENGTH];
    es tu certain qu'il ne manque pas un +1 par exemple car toutes tes autres copie de chaines le font.

  12. #12
    Membre très actif
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Février 2009
    Messages
    141
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 141
    Par défaut
    Non, le +1 est déjà pris en compte dans le define

    Par contre je n'ai rien compris, j'ai changé d'ordinateur, et sans même voir besoin de recompiler, tout fonctionnait comme ça aurait toujours du l'être.

    Pour répondre à vos questions :

    std::string n'est pas suffisant, il n'y a pas assez de méthodes pour exécuter des instructions voulues, comme les regex, ou les hashs.
    Et visiblement, il n'y a pas de problème avec les char*, donc non je ne les laisserais pas de côté.

    Et puis pour JulienDuSud, c'est très gentil de me dire que le code est buggé sans l'avoir lu, mais dans ce cas, c'est l'ordinateur qui semblait avoir un problème avec mon code (Les deux ordinateurs sur lesquels j'ai testé sont identiques)

    Enfin bon, je reviendrais au prochain problème inexplicable, merci

  13. #13
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    Citation Envoyé par Lynix Voir le message
    Non, le +1 est déjà pris en compte dans le define

    Par contre je n'ai rien compris, j'ai changé d'ordinateur, et sans même voir besoin de recompiler, tout fonctionnait comme ça aurait toujours du l'être.

    Pour répondre à vos questions :

    std::string n'est pas suffisant, il n'y a pas assez de méthodes pour exécuter des instructions voulues, comme les regex, ou les hashs.
    Et visiblement, il n'y a pas de problème avec les char*, donc non je ne les laisserais pas de côté.

    Et puis pour JulienDuSud, c'est très gentil de me dire que le code est buggé sans l'avoir lu, mais dans ce cas, c'est l'ordinateur qui semblait avoir un problème avec mon code (Les deux ordinateurs sur lesquels j'ai testé sont identiques)

    Enfin bon, je reviendrais au prochain problème inexplicable, merci
    problème de version de certaines librairies, tu peux utiliser la commande ldd sur ton exécutable/lib pour voir avec quels libs tu t'exécute.

  14. #14
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 70
    Par défaut
    Ton digest, c'est une chaîne de caractères en hexadécimal, ou c'est du binaire ? Si c'est du binaire, il contiendra des \0 donc ne peut être manipulé avec des strcpy.

    D'autre part pour qu'une chose comme ça plante :

    m_truc = ...

    il faut que this soit corrompu, ce qui peut être le résultat de tout un tas de choses (appel sur un pointeur invalide, buffer overflow dû à un strcpy sur une "chaîne" qui est en fait du binaire, etc)

  15. #15
    Membre très actif
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Février 2009
    Messages
    141
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 141
    Par défaut
    De l'hexadécimal, mais le problème à été "corrigé" simplement en changeant de pc, sans recompiler.

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

Discussions similaires

  1. C# Html Agility Pack fait planter le programme
    Par pascal4435 dans le forum C#
    Réponses: 7
    Dernier message: 01/03/2013, 13h55
  2. push_back fait planter le programme
    Par vbaddict44 dans le forum C++
    Réponses: 54
    Dernier message: 04/06/2012, 17h30
  3. Réponses: 3
    Dernier message: 01/03/2009, 18h09
  4. Réponses: 2
    Dernier message: 17/03/2007, 13h43
  5. Réponses: 1
    Dernier message: 08/06/2006, 11h01

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