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

Visual C++ Discussion :

crash et Access violation


Sujet :

Visual C++

  1. #1
    Membre du Club
    Inscrit en
    Mars 2006
    Messages
    274
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 274
    Points : 64
    Points
    64
    Par défaut crash et Access violation
    comment savoir directement la variable qui a cree une exception dans le code en lisant le message d'erreur?
    je pense que ce bout de code qui m'a cree une exception. et le programme crash directement.
    en faisant un debug j'ai trouvé que les dernieres instructions exécuté sont ce bout de code.

    est ce qu'il y a un autre moyen de liberer la memoire allouée pour la variable ch?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    char *ch;
    WCHAR *pStr2;
     
    for (int i =1; i<1000;i++)
    {
    ch =new char[string(OLE2T(pStr2)).length() + 1];
    memset(ch, '\0', string(OLE2T(pStr2)).length() + 1);
    memcpy(ch, string(OLE2T(pStr2)).begin(), string(OLE2T(pStr2)).length());
    printf("%s\n",ch);
    delete(ch);
    }

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    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 381
    Points : 41 582
    Points
    41 582
    Par défaut
    J'ai des doutes là-dessus:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memcpy(ch, string(OLE2T(pStr2)).begin(), string(OLE2T(pStr2)).length());
    Tu crées deux strings différentes, là, non?

    Ne serait-il pas plus prudent de créer une fois pour toute la string dans ton itération?

    De plus, OLE2T n'est pas la bonne macro pour les types que tu utilises.
    Si tu veux vraiment convertir de WCHAR à char, tu dois utiliser W2A...

  3. #3
    Membre du Club
    Inscrit en
    Mars 2006
    Messages
    274
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 274
    Points : 64
    Points
    64
    Par défaut
    merci pour ta rapide reponse.
    le probleme c'est que ptr2 change pour chaque iteration (bon la boucle for est mal placée mais ptr2 est lue à chaque iteration.
    a ton avis quelle est la meilleur façon de convertir wchar en char

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    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 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Généralement, j'utilise directement les fonctions de conversion de l'API Win32 : WideCharToMultiByte() notamment...

    Ou bien si on veut utiliser du C++ standard, un std::ostringstream dans lequel on insère une std::wstring, ça marche...
    Ou encore, toujours en C++ standard, il y a quelque part une classe template qui contient des fonctions narrow() et widen()...

    PS: J'ai dit une fois pour toutes dans ton itération, pas une fois pour toutes dans ta boucle...

  5. #5
    Membre du Club
    Inscrit en
    Mars 2006
    Messages
    274
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 274
    Points : 64
    Points
    64
    Par défaut
    je te remercie pour ton aide.
    j'ai trouvé cette fonction "wcstombs" qui m'as resolu le probleme de crash.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    size_t pStr2_size;	
    char *ch           ;
    pStr2_size = wcslen(pStr2) + 1;
    ch =new char[pStr2_size];
    wcstombs(ch, pStr2, pStr2_size);

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    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 381
    Points : 41 582
    Points
    41 582
    Par défaut
    ERREUR.

    Tu ne dois pas utiliser directement la taille de la chaîne d'origine pour la chaîne de destination.
    Tu dois appeler deux fois wcstombs() (la première fois avec NULL en destination), et utiliser comme taille le résultat du premier appel.

  7. #7
    Membre du Club
    Inscrit en
    Mars 2006
    Messages
    274
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 274
    Points : 64
    Points
    64
    Par défaut
    C'est à dire? comment ça devient cet exemple?
    car j'ai mis ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    pStr2_size=wcstombs(NULL, pStr2, pStr2_size);
     
    ch =new char[pStr2_size];
     
    wcstombs(ch, pStr2, pStr2_size);
    et les chaines sont tronquées( le debut c bon et le reste de la chaine des caracteres inconnus(illisibles)

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    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 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Tu oubliais le zéro terminal ET tu passais un pointeur non-initialisé...

    Un truc de ce genre devrait marcher :
    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
    #include <cassert>
    #include <cstdlib>
     
    //...
     
    {
    	//Taille du buffer: Valeur retournée par wcstombs + zéro terminal.
    	size_t cchLengthA = wcstombs(NULL, pStr2, 0);
    	size_t cchSizeA = cchLengthA+1;
     
    	//Allocation
    	char *sDest = new char[cchSizeA];
     
    	//Conversion
    	int res = wcstombs(sDest, pStr2, cchSizeA);
    	if(res != cchLengthA)
    	{
    		//Erreur.
    		std::cout << "Erreur de conversion" << std::endl;
    	}
    	else
    	{
    		//Conversion terminée.
    		std::cout << "Converti : \"" << sDest << "\"" << std::endl;
     
    		//Vérification avec une assertion :
    		//La condition devrait TOUJOURS être vraie.
    		assert(sDest[cchLengthA] == '\0');
    	}
    }
    Glossaire: cch = compte de caractères (par opposition à cb = compte d'octets)
    Length (longueur) = taille de la chaîne, sans zéro terminal.
    Size (taille) = taille de la chaîne avec zéro terminal.

  9. #9
    Membre du Club
    Inscrit en
    Mars 2006
    Messages
    274
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 274
    Points : 64
    Points
    64
    Par défaut
    ok ça marche
    mais quelle est la difference entre utiliser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    pStr2_size = wcslen(pStr2) + 1;
    et utiliser :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    size_t cchLengthA = wcstombs(NULL, pStr2, 0);
    size_t cchSizeA = cchLengthA+1;

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    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 381
    Points : 41 582
    Points
    41 582
    Par défaut
    La différence :
    C'est garanti marcher, même avec une page de code double-byte.

    Avec ton code, si UN SEUL des caractères doit se coder sur deux octets (caractères orientaux, notamment) dans la page de code courante, c'est le dépassement de buffer garanti.
    Microsoft nous propose un moyen de faire marcher à coup sûr, pourquoi s'en priver?

    Dernière minute : De plus, wcstombs est aussi disponible sur les OS unixoïdes, et beaucoup de Linux sont en UTF-8 de nos jours (et en UTF-8, BEAUCOUP de caractères prennent deux octets, à commencer par nos accents...).

  11. #11
    Membre du Club
    Inscrit en
    Mars 2006
    Messages
    274
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 274
    Points : 64
    Points
    64
    Par défaut
    Je vous remercie enormement pour toutes vos explications.

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

Discussions similaires

  1. Trouver l'origine d'un crash access violation
    Par Franck0 dans le forum C++/CLI
    Réponses: 3
    Dernier message: 04/04/2013, 11h13
  2. Réponses: 7
    Dernier message: 22/02/2005, 13h07
  3. [DELPHI][PROECEDURES STOCKES] Access violation
    Par All Jinx dans le forum Bases de données
    Réponses: 6
    Dernier message: 14/05/2004, 15h57
  4. Crash Base Access
    Par Ronald G. dans le forum Access
    Réponses: 4
    Dernier message: 04/08/2003, 11h55
  5. Réponses: 3
    Dernier message: 22/05/2002, 09h37

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