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 :

Erreur D'accès lors de la lecture


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2011
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2011
    Messages : 9
    Par défaut Erreur D'accès lors de la lecture
    Voici l'erreur : Exception non gérée à 0x00362323 dans Lab 4.exe : 0xC0000005: Violation d'accès lors de la lecture de l'emplacement 0x00237000

    Voici le code :

    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
    //Appel de la fonction :
     
    char ch1[20];
    	char ch2[20];
    	cout << "Entrez la premiere chaine de moins de 20 charactere : ";
    	cin >> ch1[20];
    	cout << endl << "Entrez la deuxieme chaine de moins de 20 charactere : ";
    	cin >> ch2[20];
    	if (Comparer(ch1, ch2) == 1)
    	{
    		cout << "Les chaines sont semblables";
    	}
    	else
    	{
    		cout << "Les chaines sont differentes";
    	}
     
    //La fonction :
     
    int Comparer (char *ch1, char *ch2)
    {
    	int i;
    	int semblable = 1;
    	for (i = 0; ch1 != '\0'; i ++)
    	{
    		if (ch1[i] != ch2[i])
    		{
    			semblable = 0;
    		}
    	}
     
    	return semblable;
    }

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    A vrai dire, ton code est un "odieux" mélange de C et de C++, et il n'est pour ainsi dire pas étonnant que tu éprouves quelque problèmes.

    Déjà ta fonction "comparer" peut parfaitement continuer bien au delà de ch[19] si, pour une raison ou une autre, le '\0' n'a pas été correctement placé, mais, en plus, C fournit une fonction toute faite(que tu retrouve en C++ dans le fichier cstring) : strchr

    De plus, tu prend un énorme risque à décider de manière arbitraire de limiter tes chaines à 20 caractères :
    • il n'y en a peut etre que deux ici, mais penses que si l'utilisateur introduit simplement "coucou", tu perdra 14 bytes par chaine (bon, en meme temps, tu me dira qu'avec l'espace mémoire dont on dispose actuellement ... mais c'est oublier un peu vite que cet espace mémoire est pris sur la pile )
    • Bien pire que cela, si l'utilisateur décide d'introduire une chaine plus longue que 20 caractères, tu ne sais jamais où vont aller les caractères surnuméraires, et ca, ca va réellement occasionner des catastrophes


    Tout cela pour dire qu'il existe une classe géniale en C++ pour la gestion des chaines de caractères : la classe string, disponible (comme tout ce qui est fournit par la norme) dans l'espace de noms std, par simple inclusion du fichier d'en-tête <string>.

    Elle n'a que des avantages : elle gère elle-meme la mémoire dont elle a besoin pour contenir l'ensemble des caractères qu'elle reçoit et elle a même la très bonne idée de fournir d'office l'opérateur == pour la comparaison, ainsi que l'opérateur += pour la concaténation!

    S'il y a donc une règle à assimiler dés le départ en C++, c'est : la STL est géniale, il faut en user et en abuser chaque fois que possible!

    Au final, ton code pourrait devenir aussi simple que
    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
        std::string ch1;
        std::sttring ch2; 
        //meme plus besoin de mettre une limite arbitraire, qui risque de toutes
        // façons (l'utilisateur étant par défaut un imbécile distrait :D)
        // de ne pas être respectée
        cout << "Entrez la premiere chaine : ";
        cin >> ch1;
        cout << endl << "Entrez la deuxieme chaine : ";
        cin >> ch2;
        if (ch1 == ch2)
        {
            cout << "Les chaines sont semblables";
        }
        else
        {
            cout << "Les chaines sont differentes";
        }
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2011
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2011
    Messages : 9
    Par défaut
    Bonjour,

    Merci de ta réponse complète et assez constructive.

    Je suis actuellement étudiant en informatique et je commence tout juste les pointeurs et mon problème en fait c'est que je doit programmer une fonction similaire à strchr en utilisant des pointeurs.

    Il serait effectivement beaucoup plus simple de suivre la solution que tu m'as donner mais j'ai la contrainte de devoir utiliser les pointeurs puisque je n'ai pas non plus le droit d'utiliser la librairie <string.h>.

    Il serait donc très aimable de ta part de m'expliquer mes erreurs dans mon codes et aussi de quelles manières je pourrais les résoudre.

    Pour le problème des char[20], je comprend tous les problèmes que ça implique mais je ne sais pas trop comment le faire autrement :/

    Merci pour ton aide

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Bon, il y a visiblement quelques bases que tu n'as pas forcément compris, car, en relisant ton code, je m'aperçois qu'il contient encore plus d'horreur que le simple fait de mélanger allègrement du C et du C++

    Comme il s'agit visiblement d'un devoir, il ne faut pas espérer que je te donnerai la solution toute faite, d'autant plus que tu sembles vouloir le faire "en dernière limite"

    Par contre, ce que je peux te dire, c'est que, quitte à placer une limite arbitraire dans le nombre de caractères que peuvent contenir tes chaines, (au passage, fais attention au fait que si tu déclare char ch1[20], il faut la place du '\0' dans les vingt caractères permis, ce qui fait que l'utilisateur ne peut en introduire que ... 19 ), il faut veiller à prendre cette limite en compte comme condition de sortie de ta boucle, y compris si on n'a pas atteint le fameux '\0' (autrement, tu risque de parcourir les 4 Gb de ta RAM, et ca fera du bruit, au sens propre comme au sens figuré )

    Ensuite, je t'inviterai à réfléchir à ce qu'est un pointeur, et à vérifier la condition de sortie de boucle que tu as écrite, en insistant sur le fait que, non seulement, tu utilise mal le pointeur ch1 (car, comme condition de sortie de boucle, ch1 est considéré comme un pointeur) mais aussi (et surtout) sur le fait que, même si tu l'utilisais correctement, si la condition est fausse à la première exécution, elle le restera, car tu ne modifie jamais ch1 par la suite.

    Enfin, si j'ai un simple conseil à te donner, s'est de veiller à ce que la variable qui te sert de compteur dans une boucle for serve comme condition de sortie de boucle (au minimum comme partie de la condition).

    Je t'ai donné plus que largement assez de pistes à explorer pour t'en sortir, maintenant, c'est à toi de jouer
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2011
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2011
    Messages : 9
    Par défaut
    Ce travail est effectivement un devoir, et je suis heureux que tu ne me donne pas directement la réponse parce que ce n'est pas non plus ce que je désire Je suis encore en apprentissage des bases des pointeurs comme tu l'as si bien noté et je vais essayer de comprendre les pistes que tu m'as si gentillement donnée

    Et au fait, est-ce que tu pourrais finir ce que tu voulais dire après
    quitte à placer une limite arbitraire dans le nombre de caractères que peuvent contenir tes chaines
    Parce que tu est tomber dans ton
    au passage
    et tu n'est pas revenu sur la façon de bien le faire

    Si je comprend bien, si je garde mon ch1[20] je devrait l'inscrire en tant que ch1[21] et écrire "\0" dans la dernière case? Et je doit aussi augmenter mon compteur dans ma boucle for pour que effectivement mon ch1 finisse par trouver le fameux "\0"

    Mais en même temps cette solution reste "odieuse" (Pour rester dans tes termes ) Donc je cherche encore une solution plus efficace et plus claire

    Merci de ton aide

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par MidNight29 Voir le message
    Et au fait, est-ce que tu pourrais finir ce que tu voulais dire après " quitte à placer une limite arbitraire dans le nombre de caractères que peuvent contenir tes chaines" ? Parce que tu est tomber dans ton "au passage" et tu n'est pas revenu sur la façon de bien le faire
    Ben, lis la fin de la phrase :
    Citation Envoyé par moi-même
    <snip>quitte à placer une limite arbitraire dans le nombre de caractères que peuvent contenir tes chaines, (<snip> ), il faut veiller à prendre cette limite en compte comme condition de sortie de ta boucle, y compris si on n'a pas atteint le fameux '\0' (autrement, tu risque de parcourir les 4 Gb de ta RAM, et ca fera du bruit, au sens propre comme au sens figuré )
    Si je comprend bien, si je garde mon ch1[20] je devrait l'inscrire en tant que ch1[21]
    Si tu veux que l'utilisateur puisse effectivement introduire 20 caractères, en effet...
    et écrire "\0" dans la dernière case?
    Pas forcément, mais cela pourrait être une bonne idée (bien que tu ne te garantisse en rien contre le fait que cin ne va pas compter le nombre de caractères, et que le risque d'aller écrire "là ou il ne faut pas" soit toujours présent :-P)
    Et je doit aussi augmenter mon compteur dans ma boucle for pour que effectivement mon ch1 finisse par trouver le fameux "\0"
    Ce que tu dois surtout faire, c'est utiliser le compteur comme condition de sortie : une fois qu'il a atteint une valeur maximale, il ne faut plus retourner dans la boucle (c'est le but des boucle "pour" : on compte le nombre de fois qu'on entre dedans, et, quand le nombre maximal est atteint, on n'entre plus dedans )
    Mais en même temps cette solution reste "odieuse" (Pour rester dans tes termes ) Donc je cherche encore une solution plus efficace et plus claire
    La solution, comme je te l'ai dit, c'est d'utiliser soit C++ soit C, mais de ne pas mélanger les deux!

    Ceci dit, le responsable est sans doute ton prof qui n'a pas encore compris que C++, même s'il partage certains concepts (comme les pointeurs) avec C et qu'il assure une certaine compatibilité avec lui, n'est en aucun cas C !!!

    Si les pointeurs sont quasi indispensables en C, il ne deviennent utiles et nécessaires en C++ qu'à partir du moment où l'on aborde l'héritage, le polymorphisme et le moyen de créer des collections d'objets dérivant d'une classe de base commune!

    Et comme tu n'as, a priori, même pas correctement compris ce qu'est un pointeur, à quoi ca correspond lorsque tu écrit char ch1[20] et ce que peut valoir ch1, j'aurais largement de quoi remettre l'enseignement de ton prof en cause (surtout qu'avec la fatigue j'ai tendance à être un peu plus méchant que d'habitude )

    Mais le fait est que nous nous battons à longueur d'année sur ce forum pour, justement, faire prendre conscience aux gens que C++ n'est absolument pas C, et qu'il faut vraiment faire la distinction entre les deux (il n'est même pas nécessaire de connaitre C pour apprendre C++, tant qu'il n'est pas question d'approfondir... et encore ) et que, chaque année en septembre et en janvier, nous sommes murs pour répéter inlassablement les même choses

    Je ne te demanderai bien sur pas de te fâcher avec ton prof, surtout en tout début d'année, mais si tu arrives à l'attirer sur le forum, nous nous chargerons de l'initier aux "bonnes pratiques" du C++ (d'autant qu'il y a une foule de discussions et de débats sur le sujet )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 01/12/2009, 01h06
  2. Réponses: 5
    Dernier message: 02/01/2009, 10h37
  3. Erreur "mémoire insuffisante" lors de la lecture d'un film
    Par nyme92 dans le forum Installation
    Réponses: 5
    Dernier message: 21/12/2008, 20h19
  4. Violation d'accès lors de la lecture
    Par Fullmetal82 dans le forum C++
    Réponses: 9
    Dernier message: 29/11/2007, 17h13
  5. erreur d'accès lors de la sauvegarde
    Par cbleas dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 23/02/2007, 17h20

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