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 :

C++: Violation d'accès à la lecture


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haut Rhin (Alsace)

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

    Informations forums :
    Inscription : Avril 2013
    Messages : 81
    Par défaut C++: Violation d'accès à la lecture
    Bonjour à tous,

    Je sais que c'est un problème assez classique, mais, malgré mes recherches, je n'ai trouvé aucune solution. En fait la compilation de mon code se passe avec succès, mais lors de l'exécution j'ai ce message d'erreur qui s'affiche:

    Exception non gérée à 0x00a3a6f9 dans graphe.exe*: 0xC0000005: Violation d'accès lors de la lecture de l'emplacement 0xcccccccc.


    J'utilise Visual Studio 2010 et voici la fonction utilisée:

    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
    graphe::graphe(char* NomFichier)
    {
        ifstream fichier(NomFichier);
        string ligne;
     
    	int num = 1;
    	while(getline(fichier, ligne) && num<=2)
    	{
    		if(num == 1) // Si num = 1, alors on lit la première ligne du fichier qui contient le tableau fs
    		{
    			int j = 0;
    			for(int i=0; i<ligne.length() ; i++)
    			{
    				if(ligne[i]!='\n')
    				{
     
    					string tmp;
    					tmp=ligne[i];
    					if(i+1<ligne.length())
    						i++; // Pour être positionné au caractère suivant
    					while(ligne[i]!=';' && i<ligne.length())
    					{
    						tmp = tmp+ligne[i];
    						i++;
    					}
    					if(i==0)
    					{
    						fs=(int*)malloc(atoi(tmp.c_str())+1);
    					}
    					fs[j]= atoi(tmp.c_str());
    					j++;
    				}
    			}
    		}
    		else
    		{
    			if(num==2) // Si num=2, alors il s'agit de la 2è ligne du fichier qui contient le tableau aps
    			{
    				int j = 0;
    				for(int i=0; i<ligne.length() ; i++)
    				{
    					if(ligne[i]!='\n')
    					{
    						string tmp;
    						tmp=ligne[i];
    						if(i+1<ligne.length())
    							i++; // Pour être positionné au caractère suivant
    						while(ligne[i]!=';' && i<ligne.length())
    						{
    							tmp = tmp+ligne[i];
    							i++;
    						}
    						if(i==0)
    						{
    							aps=(int*)malloc(atoi(tmp.c_str())+1);
    						}
    						aps[j]= atoi(tmp.c_str());
    						j++;
    					}
    				}
    			}
    		}
    		num++;
    	}
     
    	fichier.close();
    }
    Voici maintenant mon fichier main:

    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
    #include "graphe.h"
     
    #include <cstdlib>
    #include <iostream>
     
    using namespace std;
     
    int main(int argc, char *argv[])
    {
        char* NomFichier = "essai.txt";
     
    	graphe g(NomFichier);
     
    	for(int i=1; i<=g.fs[0];i++)
    		cout<< g.fs[i] << " ";
    	cout<<endl;
     
    	for(int i=1; i<=g.aps[0];i++)
    		cout<< g.aps[i] << " ";
     
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    Je précise que fs[0] contient le nombre d'élément du tableau fs -1 (sans la première case donc) et idem pour le tableau aps.

    Ce que la fonction graphe est censé faire est, à partir du fichier txt, mettre les nombres de la 1è ligne dans le tableau fs et ceux de la deuxième dans le tableau aps. Ces nombres sont séparés par des points virgules.

    Merci d'avance.

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Tu as fait du pas ?
    Essayé de mettre des traces ?

    Je t'avoue qu'à cette heure-ci, j'ai un peu la flemme de lire ton code.

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haut Rhin (Alsace)

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

    Informations forums :
    Inscription : Avril 2013
    Messages : 81
    Par défaut
    Tu veux dire quoi par mettre des traces et faire du pas ?

    Petite précision que je n'ai pas mis dans mon premier post : quand l'erreur s'affiche, j'ai la première boucle for dans le main qui est pointée par une flèche (donc l'erreur serait causé par celle-ci mais pourquoi je l'ignore).

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par seb68270 Voir le message
    Petite précision que je n'ai pas mis dans mon premier post : quand l'erreur s'affiche, j'ai la première boucle for dans le main qui est pointée par une flèche (donc l'erreur serait causé par celle-ci mais pourquoi je l'ignore).
    Si ça arrive sur la boucle de ton for, c'est que la construction de ton graphe s'est a priori bien passée.
    Ça doit planter sur g.fs(). Mais on n'a pas le code de cette fonction.

  5. #5
    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,

    Déjà, quand je vois cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fs=(int*)malloc(atoi(tmp.c_str())+1);
    j'ai peur! Et pour plusieurs raisons:
    • D'abord, cela sous entend que temp est une chaine de caractères qui représente une valeur numérique, ce qui reste à démontrer
    • Ensuite parce que l'on n'utilise jamais malloc en C++
    • Enfin, parce que cette allocation dynamique de mémoire a lieu dans une boucle, et qui plus est dans des boucles imbriquées. Je soupçonne donc que tu seras très rapidement confronté à une fuite mémoire
    Ta logique est vraiment pour le moins, humm, disons surprenante je te conseillerais très vivement de la revoir un tout petit peu, et, surtout, d'utiliser les fonctionnalités propres à C++ : les tableaux de taille dynamique sont gérés avec std::vector et la conversion se fait soit avec les classes stringstream, soit avec les fonctions adaptées que C++11 nous apporte (stoi, stol, stoll, stoul, stoull)
    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

  6. #6
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haut Rhin (Alsace)

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

    Informations forums :
    Inscription : Avril 2013
    Messages : 81
    Par défaut
    Citation Envoyé par oodini Voir le message
    Si ça arrive sur la boucle de ton for, c'est que la construction de ton graphe s'est a priori bien passée.
    Ça doit planter sur g.fs(). Mais on n'a pas le code de cette fonction.
    En fait, j'ai créé une classe graphe dont 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
    class graphe
    {
    public:
     
        graphe(char* NomFichier);
        graphe(int** adj);
     
        int* fs;
        int* aps;
        int** adj;
     
    };
    D'où donc la ligne "graphe g(NomFichier);" dans le main.

    j'ai peur! Et pour plusieurs raisons:
    D'abord, cela sous entend que temp est une chaine de caractères qui représente une valeur numérique, ce qui reste à démontrer
    Ensuite parce que l'on n'utilise jamais malloc en C++
    Enfin, parce que cette allocation dynamique de mémoire a lieu dans une boucle, et qui plus est dans des boucles imbriquées. Je soupçonne donc que tu seras très rapidement confronté à une fuite mémoire
    Ta logique est vraiment pour le moins, humm, disons surprenante je te conseillerais très vivement de la revoir un tout petit peu, et, surtout, d'utiliser les fonctionnalités propres à C++ : les tableaux de taille dynamique sont gérés avec std::vector et la conversion se fait soit avec les classes stringstream, soit avec les fonctions adaptées que C++11 nous apporte (stoi, stol, stoll, stoul, stoull)
    Concernant la fuite mémoire c'est possible vu que j'ai un problème de violation d'accès à la lecture. Par contre, je ne peux pas utiliser un vecteur vu que je dois utiliser un tableau. Je fais c'est dans le cadre d'un projet pour la fac en fait et justement fs est un tableau déclaré comme ceci:

  7. #7
    Membre chevronné
    Profil pro
    Consultant en technologies
    Inscrit en
    Octobre 2013
    Messages
    158
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en technologies

    Informations forums :
    Inscription : Octobre 2013
    Messages : 158
    Par défaut
    Citation Envoyé par seb68270 Voir le message
    En fait, j'ai créé une classe graphe dont voici le code:

    [Concernant la fuite mémoire c'est possible vu que j'ai un problème de violation d'accès à la lecture. Par contre, je ne penses pas pouvoir utiliser un vecteur vu que je dois utiliser un tableau (d'où le "int* fs;" dans la classe). Après je peux me tromper ...
    * Ce genre d'erreur c'est typique d'une lecture au mauvais index d'un tableau.

    * Pourquoi dois-tu utiliser un tableau (exercice, une contrainte particulière ?) dans au moins 90% des cas std::vector (et en cpp11 std::array) seront à préférer au tableau à la papy (Je doute pas qu'un conteneur complexe dont la taille peut se changer on the fly a un cout en terme de temps de calcul, mais sauf quelques applications, ce cout est compensé par le gain de développeur qui n'a pas à gerer de fuite de mémoire ou de Segfault).

    * En c++ un tableau dynamique (à la papy) c'est int* tab = new int[N]; (et se libère avec delete[]) les malloc c'est du C. Si tu alloue de la mèmoire à la main tu doit la liberer à la main (Sinon fuite de mémoire), le problème c'est que tu as vite fait d'oublier un corner-case et d'écrire une fonction qui dans un cas sur cents ne désalloue pas de la mémoire. Si tu fais 10 000 itérations et que ton objet fait 1 MB c'est pas grave. Si tu fais milles fois plus ou que tes objets sont 1000 fois plus gros tu plante ta machine. (Mais bon même de petits objets sur des petites boucles c'est à éviter). L'interet du vector/array (mais aussi des smart pointers) c'est de pas avoir à faire ce boulot à la main et donc d'éviter les corner-case

Discussions similaires

  1. Violation d'accès en lecture écriture
    Par 3Fred9 dans le forum Langage
    Réponses: 5
    Dernier message: 30/03/2010, 14h36
  2. Réponses: 5
    Dernier message: 01/12/2009, 01h06
  3. Réponses: 7
    Dernier message: 13/08/2009, 09h01
  4. Réponses: 5
    Dernier message: 02/01/2009, 10h37
  5. Violation d'accès lors de la lecture
    Par Fullmetal82 dans le forum C++
    Réponses: 9
    Dernier message: 29/11/2007, 17h13

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