Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème de violation d'accès

    17 avril 2019 à 14:16:30

    Bonjour voilà mon code et lorsque je le compile j'obtiens l'erreur suivante sous visual studio : Exception levée à 0x0F94E559 (ucrtbased.dll) dans TestUnitaire_JOY9.exe : 0xC0000005 : Violation d'accès lors de l'écriture à l'emplacement 0x000A3534.

    Mon code récupère des données contenu dans un fichier texte pour les introduire dans un tableau 2d à allocation dynamique.

    Code:

    void JOMA_TestCAN(void)
    {
    	int caractereLu = 0, i = 0, position = 0, position_temp = 0, longD = 0, j = 0, g = 0 , h= 0 , taille1 = 100, taille2 = 100;
    	char *chaine = NULL;
    	char **Copie_Fichier = NULL; // Ce pointeur va servir de tableau après l'appel du malloc (tableau à 2 dimenssions donc 2 etoiles pointeur)
    
    	//Gestion des fichier textes
    	FILE* fichier_In = NULL; //Le pointeur est initialisé a NULL
    	fichier_In = fopen("C:\\Users\\Input.txt", "r"); 
    
    	FILE* fichier_Out = NULL; //Le pointeur est initialisé a NULL
    	fichier_Out = fopen("C:\\Users\\Output.txt", "w");
    	
    	//Allocation dynamique 1ere dimension
    	Copie_Fichier = malloc(taille1 * sizeof(*Copie_Fichier)); // On alloue de la mémoire pour le tableau
    	if (Copie_Fichier == NULL) // On vérifie si l'allocation a marché ou non
    	{
    		printf("Allocation dynamique mauvaise");
    		exit(0); // On arrête tout
    	}
    
    	//Allocation dynamique 2eme dimension
    	for (i = 0; i < taille1; i++) 
    	{
    		Copie_Fichier[i] = malloc(taille2 * sizeof(**Copie_Fichier));       //On alloue des tableaux de 'taille2' variables.
    		if (Copie_Fichier[i] == NULL) //En cas d'erreur d'allocation
    		{
    			free(Copie_Fichier[i]); //Il faut libérer la mémoire déjà allouée
    			printf("Erreur lors de l'allocation");
    			exit(0);
    		}
    	}
    	
    	//Allocation dynamique
    	chaine = malloc(taille1 * sizeof(*chaine)); // On alloue de la mémoire pour le tableau
    	if (chaine == NULL) // On vérifie si l'allocation a marché ou non
    	{
    		printf("Allocation dynamique mauvaise");
    		exit(0); // On arrête tout
    	}
    
    	if ((fichier_In != NULL) && (fichier_Out != NULL))
    	{
    		for (h = 0; h < 2;h++) //A changer le h en fonction du nombre de tests à réaliser
    		{
    	
    			while (fgets(chaine, taille1, fichier_In) != NULL)
    			{
    				strcpy(Copie_Fichier[i], chaine);
    				i++;
    			}
    	
    		}
    	
    		fclose(fichier_In); // On ferme le fichier qui a été ouvert
    		fclose(fichier_Out); // On ferme le fichier qui a été ouvert
    		free(Copie_Fichier);
    		free(chaine);
    
    	else
    	{
    		// On affiche un message d'erreur si on veut
    		printf("Impossible d'ouvrir les fichiers Input.txt et Output.txt");
    	}
    }

    L'erreur apparais à la ligne 49.

    -
    Edité par TomGuy 17 avril 2019 à 15:03:33

    • Partager sur Facebook
    • Partager sur Twitter
      17 avril 2019 à 14:59:09

      Hello,

      Ligne 49 et 50: pas i, mais h ! Juste pour info: à cet endroit, i vaut taille1.

      Edit:

      • le free() pour Copie_Ficher n'est pas correct: il faut d'abord désallouer tous les Copie_Fichier[i]
      • tu ne désalloues rien si les fichiers (ou un des deux fichiers) n'ont pas pu être ouverts
      • pourquoi tester l'ouverture des fichiers après  avoir fait les allocations ?
      • et des commentaires comme ceux des lignes 8, 11, 55 et 56, ça ne sert qu'à alourdir le code
      • un peu de constance dans les noms de variables ne ferait pas de mal: fichier_In mais Copie_Fichier. Et évite le franglais: tous les noms de variables dans une seule langue.

      -
      Edité par edgarjacobs 17 avril 2019 à 15:11:44

      • Partager sur Facebook
      • Partager sur Twitter

      On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

        17 avril 2019 à 15:37:03

        edgarjacobs a écrit:

        Hello,

        Ligne 49 et 50: pas i, mais h ! Juste pour info: à cet endroit, i vaut taille1.

        Edit:

        • le free() pour Copie_Ficher n'est pas correct: il faut d'abord désallouer tous les Copie_Fichier[i]
        • tu ne désalloues rien si les fichiers (ou un des deux fichiers) n'ont pas pu être ouverts
        • pourquoi tester l'ouverture des fichiers après  avoir fait les allocations ?
        • et des commentaires comme ceux des lignes 8, 11, 55 et 56, ça ne sert qu'à alourdir le code
        • un peu de constance dans les noms de variables ne ferait pas de mal: fichier_In mais Copie_Fichier. Et évite le franglais: tous les noms de variables dans une seule langue.

        -
        Edité par edgarjacobs il y a 6 minutes


        Merci pour ta reponse déja.

        Ensuite pour la ligne 49 50 c'est normal que ce soit i au lieu de h car c'est une boucle différente de celle de h qui elle sert a autre chose dans mon code entier (j'ai mis seulement ce qui était nécessaire à la compréhension de mon problème).

        Pour ton premier point et ton second point ce que j'ai compris c'est que je désallouais trop tôt dans mon programme je l'ai donc déplacé à la fin ligne : 53 à 56.

        Pour ton troisième point en gros tu me conseille de faire mes allocations seulement dans le cas où l'ouverture de mes fichiers s'est bien passée ? c'est à dire les placer à la ligne 42 par exemple.

        Effectivement j'ai supprimé les commentaires inutiles, je referais le tri un peu après encore.

        Ah oui tu as raison je vais changer cela.

        Voila mon nouveau code :

        void JOMA_TestCAN(void)
        {
            int caractere_Lu = 0, i = 0, position = 0, position_Temp = 0, longD = 0, j = 0, g = 0 , h= 0 , taille1 = 100, taille2 = 100;
            char *chaine = NULL;
            char **copie_Fichier = NULL; // Ce pointeur va servir de tableau après l'appel du malloc (tableau à 2 dimenssions donc 2 etoiles pointeur)
         
            //Gestion des fichier textes
            FILE* fichier_Entree = NULL;
            fichier_In = fopen("C:\\Users\\Input.txt", "r");
         
            FILE* fichier_Sortie = NULL;
            fichier_Out = fopen("C:\\Users\\Output.txt", "w");
             
            //Allocation dynamique 1ere dimension
            copie_Fichier = malloc(taille1 * sizeof(*copie_Fichier)); // On alloue de la mémoire pour le tableau
            if (copie_Fichier == NULL) // On vérifie si l'allocation a marché ou non
            {
                printf("Allocation dynamique mauvaise");
                exit(0); // On arrête tout
            }
         
            //Allocation dynamique 2eme dimension
            for (i = 0; i < taille1; i++)
            {
                copie_Fichier[i] = malloc(taille2 * sizeof(**copie_Fichier));       //On alloue des tableaux de 'taille2' variables.
                if (copie_Fichier[i] == NULL) //En cas d'erreur d'allocation
                {
                    printf("Erreur lors de l'allocation");
                    exit(0);
                }
            }
             
            //Allocation dynamique
            chaine = malloc(taille1 * sizeof(*chaine)); // On alloue de la mémoire pour le tableau
            if (chaine == NULL) // On vérifie si l'allocation a marché ou non
            {
                printf("Allocation dynamique mauvaise");
                exit(0); // On arrête tout
            }
         
            if ((fichier_Entree != NULL) && (fichier_Sortie!= NULL))
            {         for (h = 0; h < 2;h++) //A changer le h en fonction du nombre de tests à réaliser         {                   while (fgets(chaine, taille1, fichier_Entree) != NULL)             {                 strcpy(copie_Fichier[i], chaine);                 i++;             }               } for (i = 0; i < taille1; i++)      { free(copie_Fichier[i]); //Il faut libérer la mémoire déjà allouée      }               fclose(fichier_Entree);         fclose(fichier_Sortie);         free(copie_Fichier);         free(chaine);   }     else     {         // On affiche un message d'erreur si on veut         printf("Impossible d'ouvrir les fichiers Input.txt et Output.txt");     } }

        -
        Edité par TomGuy 17 avril 2019 à 15:40:57

        • Partager sur Facebook
        • Partager sur Twitter
          17 avril 2019 à 16:14:13

          Ça ne peut toujours pas fonctionner !

          En sortant du for ligne 31, i vaut taille1. Ligne 47, tu vas donc copier chaine dans copie_Fichier[taille1], qui n'existe pas.

          -
          Edité par edgarjacobs 17 avril 2019 à 16:15:28

          • Partager sur Facebook
          • Partager sur Twitter

          On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

            17 avril 2019 à 16:25:49

            edgarjacobs a écrit:

            Ça ne peut toujours pas fonctionner !

            En sortant du for ligne 31, i vaut taille1. Ligne 47, tu vas donc copier chaine dans copie_Fichier[taille1], qui n'existe pas.

            -
            Edité par edgarjacobs il y a 8 minutes


            Mais alors si je remet mon i à 0 avant la ligne 45 cela devrais résoudre le problème ou alors je n'ai pas compris qqc.
            • Partager sur Facebook
            • Partager sur Twitter
              17 avril 2019 à 16:44:24

              TomGuy a écrit:

              edgarjacobs a écrit:

              Ça ne peut toujours pas fonctionner !

              En sortant du for ligne 31, i vaut taille1. Ligne 47, tu vas donc copier chaine dans copie_Fichier[taille1], qui n'existe pas.

              -
              Edité par edgarjacobs il y a 8 minutes


              Mais alors si je remet mon i à 0 avant la ligne 45 cela devrais résoudre le problème....

              Là, d'accord

              -
              Edité par edgarjacobs 17 avril 2019 à 17:05:20

              • Partager sur Facebook
              • Partager sur Twitter

              On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                17 avril 2019 à 16:49:24

                edgarjacobs a écrit:

                TomGuy a écrit:

                edgarjacobs a écrit:

                Ça ne peut toujours pas fonctionner !

                En sortant du for ligne 31, i vaut taille1. Ligne 47, tu vas donc copier chaine dans copie_Fichier[taille1], qui n'existe pas.

                -
                Edité par edgarjacobs il y a 8 minutes


                Mais alors si je remet mon i à 0 avant la ligne 45 cela devrais résoudre le problème....

                Là, d'accord.

                Mais même en rajoutant le i=0 j'ai toujours cette erreur (Violation d'accès lors de l'écriture à l'emplacement 0x5F594F4A.) sur la ligne : 
                strcpy(copie_Fichier[i], chaine);



                -
                Edité par TomGuy 17 avril 2019 à 16:50:02

                • Partager sur Facebook
                • Partager sur Twitter
                  17 avril 2019 à 17:03:24

                  Mais combien de fois fais-tu le fgets() ligne 45 ? Si c'est plus de taille1 fois, normal que ça plante.

                  Pour éviter cela, tu peux mettre

                  i=0;
                  while (i<taille1 && fgets(chaine, taille1, fichier_Entree) != NULL) {
                  	strcpy(copie_Fichier[i], chaine);
                  	i++;
                  }
                  if(i==taille1)
                  	puts("il se peut que tout le fichier n'ait pas été lu");

                  Au fait, quel est le but de cette fonction ? Car si c'est copier le fichier d'entrée dans le fichier de sortie, il y a nettement plus simple

                  -
                  Edité par edgarjacobs 17 avril 2019 à 17:09:47

                  • Partager sur Facebook
                  • Partager sur Twitter

                  On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                    18 avril 2019 à 9:47:20

                    Je fais le fgets une quinzaine de fois donc il est inférieur à taille1.

                    J'ai intégrer le bout de code que tu m'as donner mais j'ai toujours ce problème de violation d'accès.

                    Le but de ma fonction est de récupérer les valeurs de variables contenues dans un fichier texte externe pour les les passer dans un programme de test et ensuite récupérer les résultats obtenus lors du test dans un autre fichier texte.

                    • Partager sur Facebook
                    • Partager sur Twitter
                      18 avril 2019 à 11:08:37

                      Bonjour,

                      Il y a des confusions entre taille1 et taille2. Difficile de donner une solution avec des noms aussi explicites. Mais par exemple les copie_fichier[i] sont réservés à une taille2 et remplis avec un buffer chaine alloué à taille1. Ici les valeurs sont égales, mais en changer provoquera au mieux une violation d'accès.

                      La variable i doit être remise à zéro avant la ligne 42 (et après la ligne 31) sinon les données pour les premières itérations de h seront perdues. Autre manière : ne pas utiliser une même variable pour 2 choses différentes!
                      Autre manière : on peut déclarer une variable de boucle invisible à l'extérieur, dans cet unique cas on peut les appeler i,j,k,m,n et ne jamais déclarer ailleurs de variables de moins de 4 lettres.

                      Après un fgets(), rien ne dit que l'on a obtenu une chaîne qui inclut son terminateur (si le \n n'a pas été vu avant la taille attendue on obtient un buffer sans terminateur.) faire un strcat() dans ce cas produira au mieux une violation d'accès.

                      J'espère avoir aidé

                      • Partager sur Facebook
                      • Partager sur Twitter

                      En recherche d'emploi.

                        18 avril 2019 à 14:15:49

                        Bonjour,

                        Taille 1 correspond aux nombres de colonnes et taille 2 correspond aux nombres de lignes, mais effectivement ce serais plus simple que je change leur nom.

                        Au niveau des variables de boucles j'ai réorganisé tout ça.

                        A propos du fgets lorsque je passe en mode debugage j'observe bien a la fin de ma chaîne le \n pour dire que l'on est bien arrivé au bout.

                        • Partager sur Facebook
                        • Partager sur Twitter
                          18 avril 2019 à 15:58:44

                          Re,-

                          Si tout ton fichier peut tenir en mémoire (ce qui semble être le cas), alors il y a beaucoup plus simple comme méthode. Tu alloues un buffer de la taille de ton fichier, tu lis (avec fread() et l'open en mode "rb") tout le fichier, puis tu découpes le buffer avec strtok()

                          -
                          Edité par edgarjacobs 18 avril 2019 à 15:59:02

                          • Partager sur Facebook
                          • Partager sur Twitter

                          On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                            18 avril 2019 à 21:05:49

                            Hello,

                            Je te propose ce code qui permet de faire ce que tu souhaites.
                            Si tu as des questions, n'hésites pas. Je n'ai pas commenté exprès.
                            Tu peux essayer de te l'approprier en le refaisant à ta manière et repartir à 0.

                            #include <stdio.h>
                            #include <stdlib.h>
                            #include <limits.h>
                            #include <string.h>
                            
                            
                            size_t *sz_allocate( size_t x )
                            {
                                size_t *s = NULL;
                                if ( ( s = malloc( x*sizeof( *s ) ) ) )
                                    for ( size_t i=0 ; i<x ; i++ )
                                        s[i] = 0;
                            
                                return s;
                            }
                            
                            char *c_allocate( size_t x )
                            {
                                char *s = NULL;
                                if ( ( s = malloc( x*sizeof( *s ) ) ) )
                                        s[x-1] = '\0';
                            
                                return s;
                            }
                            
                            void c_2D_deallocate( char **p, size_t x )
                            {
                                if (p)
                                {
                                    size_t i;
                                    for ( i=0 ; i<x ; i++ )
                                        free(p[i]), p[i]=NULL;
                            
                                    free(p), p=NULL;
                                }
                            }
                            
                            char **c_2D_allocate( size_t x, size_t **y )
                            {
                                char **p = NULL;
                                if ( x > 0 )
                                {
                                    if ( ( p = malloc( x*sizeof( *p ) ) ) )
                                    {
                                        if ( (*y) != NULL )
                                        {
                                            for ( size_t i=0 ; i<x ; i++ )
                                            {
                                                if ( ( p[i] = c_allocate( (*y)[i] ) ) )
                                                    for ( size_t j=0 ; j<(*y)[i] ; j++ )
                                                        p[i][j] = '\0';
                            
                                                else c_2D_deallocate( p, i-1 ), i=x;
                                            }
                                        }
                                        else
                                        {
                                            if ( ( (*y) = malloc( x*sizeof( size_t ) ) ) )
                                                for ( size_t i=0 ; i<x ; i++ )
                                                    p[i] = NULL, (*y)[i]=0;
                                        }
                                    }
                                }
                                return p;
                            }
                            
                            void sz_2D_deallocate( size_t **p, size_t x )
                            {
                                if (p)
                                {
                                    size_t i;
                                    for ( i=0 ; i<x ; i++ )
                                        free(p[i]), p[i]=NULL;
                            
                                    free(p), p=NULL;
                                }
                            }
                            
                            size_t **sz_2D_allocate( size_t x, size_t **y )
                            {
                                size_t **p = NULL;
                                if ( x > 0 )
                                {
                                    if ( ( p = malloc( x*sizeof( *p ) ) ) )
                                    {
                                        if ( (*y) != NULL )
                                        {
                                            for ( size_t i=0 ; i<x ; i++ )
                                            {
                                                if ( ( p[i] = sz_allocate( (*y)[i] ) ) )
                                                    for ( size_t j=0 ; j<(*y)[i] ; j++ )
                                                        p[i][j] = 0;
                            
                                                else sz_2D_deallocate( p, i-1 ), i=x;
                                            }
                                        }
                                        else
                                        {
                                            if ( ( (*y) = malloc( x*sizeof( size_t ) ) ) )
                                                for ( size_t i=0 ; i<x ; i++ )
                                                    p[i] = NULL, (*y)[i]=0;
                                        }
                                    }
                                }
                                return p;
                            }
                            
                            char *file_to_string( const char *path, size_t *f_sz )
                            {
                                *f_sz = 0;
                                char *str_out=NULL;
                                if ( path && f_sz )
                                {
                                    FILE *pFile=NULL;
                                    if ( (pFile=fopen(path,"rb")) )
                                    {
                                        char *t_realloc = NULL;
                                        char buffer;
                                        size_t read_byte = 0 ;
                                        while( 0<(read_byte=fread(&buffer, sizeof(char), 1, pFile)) )
                                        {
                                            if ( (t_realloc=realloc(str_out, (++*f_sz)*sizeof(*str_out))) )
                                               str_out=t_realloc, str_out[*f_sz-1]=buffer;
                            
                                            else free(str_out), read_byte=-1;
                                        }
                                        if ( (t_realloc=realloc(str_out, (++*f_sz)*sizeof(*str_out))) )
                                            str_out=t_realloc, str_out[*f_sz-1]='\0';
                                    }
                                    fclose(pFile);
                                }
                                return str_out;
                            }
                            
                            size_t str_count_occurence( char *s, const char c )
                            {
                                size_t count = 0;
                                if( s )
                                {
                                    size_t s_sz = strlen( s );
                                    for ( size_t i=0 ; i<s_sz ; i++ )
                                        if ( s[i] == c )
                                            count++;
                                }
                                return count;
                            }
                            
                            size_t *str_row_sz( char *s, size_t *x )
                            {
                                size_t *row = NULL;
                                if ( s )
                                {
                                    *x = str_count_occurence( s, '\n' );
                                    if ( ( row = malloc( (*x)*sizeof(*row) ) ) )
                                    {
                                        size_t s_sz = strlen( s ); size_t line = 0; size_t row_sz = 0;
                                        for ( size_t i=0 ; i<s_sz && line<=*x ; i++ )
                                        {
                                            if ( s[i] != '\n' )
                                                row_sz++;
                            
                                            if ( s[i] == '\n' )
                                                row[line] = ++row_sz, line++, row_sz = 0;
                                        }
                                    }
                                }
                                return row;
                            }
                            
                            char **str_to_2D( char *s, size_t **row, size_t *line )
                            {
                                char **t = NULL;
                                if( s )
                                {
                                    size_t s_sz = strlen( s );
                                    size_t  dim_x = 0;
                                    size_t *dim_y = str_row_sz( s, &dim_x );
                                    if ( ( t = c_2D_allocate( dim_x, &dim_y ) ) )
                                    {
                                        size_t x=0; size_t y=0;
                                        for( size_t i=0 ; i<s_sz ; i++ )
                                        {
                                            if ( s[i] == '\n' )
                                               t[x][y] = '\0', x++, y=0;
                            
                                            if ( s[i] != '\n')
                                                t[x][y] = s[i], y++;
                                        }
                                        (*row) = dim_y, *line = dim_x;
                                    }
                                }
                                return t;
                            }
                            
                            char **file_to_2D( const char *path, size_t **row, size_t *line )
                            {
                                char **t = NULL;
                                if ( path )
                                {
                                    char *s = NULL; size_t s_sz = 0; size_t x = 0;
                                    if ( ( s = file_to_string( path, &s_sz ) ) )
                                    {
                                        size_t *y = NULL;
                                        if ( ( t = str_to_2D( s, &y, &x ) ) )
                                            (*row) = y, *line = x;
                                    }
                                }
                                return t;
                            }
                            
                            void display_2D_c( char **t, size_t x, size_t *y )
                            {
                                for( size_t i=0 ; i<x ; i++, printf("\n") )
                                    for ( size_t j=0; j<y[i] ; j++ )
                                        printf("%c", t[i][j]);
                            }
                            
                            int main()
                            {
                                char **t = NULL; size_t *row = NULL;  size_t line = 0;
                                if ( ( t = file_to_2D( "F:\\test.txt",  &row, &line ) ) )
                                    display_2D_c( t, line, row ), c_2D_deallocate( t, line ), free(row);
                            
                                getchar();
                                return 0;
                            }
                            



                            -
                            Edité par aneonymous 18 avril 2019 à 21:07:14

                            • Partager sur Facebook
                            • Partager sur Twitter
                              19 avril 2019 à 9:21:14

                              Merci pour vos réponses edgarjacobs et aneonymous je vais regardé vos solutions.
                              • Partager sur Facebook
                              • Partager sur Twitter
                                20 avril 2019 à 20:52:07

                                As tu réussi a t en sortir ?
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  23 avril 2019 à 12:17:21

                                  aneonymous a écrit:

                                  As tu réussi a t en sortir ?


                                  Oui j'ai réussi à faire ce que je voulais merci encore.
                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  Problème de violation d'accès

                                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                  • Editeur
                                  • Markdown