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");
}
}
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
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
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");
}
}
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
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
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.
Il y a des confusions entre taille1et 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 idoit ê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 hseront 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,net 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.
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.
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
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
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.
Oui j'ai réussi à faire ce que je voulais merci encore.
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.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
En recherche d'emploi.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent