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++/CLI Discussion :

Unhandled exception of type 'System.AccessViolationException' sur strcat


Sujet :

C++/CLI

  1. #1
    Candidat au Club
    Homme Profil pro
    Stagiaire
    Inscrit en
    Juin 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Chine

    Informations professionnelles :
    Activité : Stagiaire
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2012
    Messages : 6
    Points : 4
    Points
    4
    Par défaut Unhandled exception of type 'System.AccessViolationException' sur strcat
    Bonjour,

    je suis debutant en c++ et doit developper un programme Windows Form avec visual c++ 2010.
    J'essaye de concatener des chaines de la facon suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	char* returnedValue(0);
    	char* plop(0);
    	plop = "plop";
    	returnedValue = "Mess envoye : ";
    	strcat(returnedValue, plop);
    L'execution de ce code fait bloquer le programme sur la ligne 5, et renvoit une erreur :

    An unhandled exception of type 'System.AccessViolationException' occurred

    Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
    Une idee quelconque de l'origine possible de cette erreur?
    Toute aide est plus qu'utile.
    Merci d'avance,

    Cordialement,

    Gabriel

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Février 2005
    Messages : 5 171
    Points : 12 293
    Points
    12 293
    Par défaut
    Windows Form, c'est du C++/CLI pas du C++.

    C++/CLI est une extension du C++.

    Là, t'as eu un exception .NET ('System.AccessViolationException' ) car tu est en C++/CLI.

    Mais le problème est le même en C++ et en C++/CLI.

    Tu initialises tes variables de type char* avec des constantes qui sont stockées dans le binaire dans une zone particulaire, la "variable" initialisé. Quand le chargeur de l'OS charge le programme en mémoire, cette donne correspond à un segment en mémoire dit des "variable" initialisées.
    Toutes les constantes y sont mises les une à la suite des autres.

    Donc, quand tu affectes <plop = "plop";> la valeur de la variable plop est une adresse mémoire dans la zone des "variable" initialisées.
    Idem pour returnedValue.

    strcat (c'est une fonction C et pas C++), détermine la fin de la chaine de caractères destination (1er paramètre) en cherchant un caractère '\0' (fin de chaine), puis copie octet par octet à partir du la case contenant '\0' les casses mémoire commençant à la valeur du second paramètre jusqu'à la détection d'un caractère '\0' (fin de chaine) "dans" la chaine du second paramètre. strcar copie le '\0' en fin de chaîne, ainsi la représentation du chaine de caractère C reste conforme à la norme C.

    Le problème, c'est que si vous faites cela, vous commencez par remplacer le '\0' en fin de la chaine de caractère destination par le premier caractère de la chaine source (second paramètre), puis vous allez copiez le second caractère de la chaine source dans la cellule mémoire qui suit. Le problème, c'est que cette cellule mémoire, c'est très vraisemblablement une autre "constante" ou tout autre données ou code du programme.
    En C ou avec un compilateur C++ archaïque vous êtes bon pour un bon gros plantage aléatoire.
    En C++/CLI, cette zone où sont stockées les constantes est protégés en écriture pour éviter ce genre de boulette très commune. Et oui, vous n'êtes pas le premier.

    Alors, le plus simple c'est d'utiliser les fonctionnalités C++ ou C++CLI et pas les fonctions C d'il y a 40 ans.

    C++/CLI:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    System::String^ returnedValue = "Mess envoye : ";
    System::String^ plop = "plop";
    returnedValue += plop;

  3. #3
    Candidat au Club
    Homme Profil pro
    Stagiaire
    Inscrit en
    Juin 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Chine

    Informations professionnelles :
    Activité : Stagiaire
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2012
    Messages : 6
    Points : 4
    Points
    4
    Par défaut
    Merci pour cet eclaircissement.
    Il est vrai que je melange completement toutes ces notions. Pour un debutant, ca fait beaucoup d'un coup.
    Le probleme est que je dois migrer du code ecrit en VC++6 vers VC++ 2010, et que tout ce code utilise ce que je crois etre du C.
    Donc la conversion de donnees me pose pas mal de problemes.

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Février 2005
    Messages : 5 171
    Points : 12 293
    Points
    12 293
    Par défaut
    Approche défensive, ne faire aucun modification dans le code C natif.
    La tambouille sur les chaines existe donc déjà en C, laissez-la dans le code C.

    Vous ne devez faire de conversion qu'entre les données qui circulent entre le code managé et le code non managé.

    Il faut donc que vous ayez une définition stricte de cette frontière, comme dans des projets différents.

    Les projets en C++ non managé => les projets VC++6 automatiquement migré (ou pas je sais plus) en VS2010. Sauf le projet de l'IHM qui n'utilise pas Windows Form.

    Un projet en C++/CLI contenant la nouvelle IHM.

    Vous n'aurez qu'a convertir, dans le code C++/CLI les donnés venant de la couche business des autres projets.

Discussions similaires

  1. Réponses: 4
    Dernier message: 09/09/2009, 11h28
  2. Réponses: 1
    Dernier message: 16/07/2007, 09h47
  3. Réponses: 3
    Dernier message: 30/03/2007, 11h57
  4. Réponses: 1
    Dernier message: 27/03/2007, 09h50
  5. Réponses: 2
    Dernier message: 11/10/2006, 10h36

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