Problème de libération de l'éspace dynamique alloué [Résolu]

Signaler
Messages postés
393
Date d'inscription
lundi 22 juin 2009
Statut
Membre
Dernière intervention
23 décembre 2011
-
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
-
Bonsoir,
J'ai un fichier contient deux champs: objet et attribut nommé "exemple.txt" :

2 11
4 11
10 10
5 O1
.....
.....

Sachant que on a la même taille pour tous les attributs de tous les objets dans notre exemple on a la taille = 2.
Cette taille peut changer d'un exemple à l'autre donc on ne connait pas la taille d'attribut en avance.

Je voudrais calculer la taille de l'attribut puis vérifier si on dans ce fichier si on a au moins un objet qui possède un attribut tout à 1 c'est à dire la chaine "11" dans notre cas.
la fonction verifier() nous retourne 1 si il existe la chaine "11" sinon O.

Voici mon essai :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int verifier(int taille)
{
FILE *fp;
char *chaine,s[100],attribut[32];
int i,trouve=0,objet=0;
chaine = (char *) malloc(taille);
for(i=0; i < taille; i++)
chaine[i]='1';
chaine[taille]='\0';
printf("chaine=%s\n",chaine);
pFTrie = fopen("exemple.txt","r");
while (fgets(s, 100, fp))
{
sscanf(s,"%d%s",objet,attribut);
if(memcmp(attribut,chaine,taille))
{
free(chaine);
fclose(fp);
return 1;
}
}
free(chaine);
fclose(fp);
return 0;
}
 
int main()
{
FILE *fp;
int trouve=0,taille;
fp=fopen("exemple.txt");
While (fgets(s,100,fp))
sscanf(s,"%d%s",&objet,attribut);
taille=strlen(attribut);
trouve = verifier(taille);
printf("valeur de retour %d\n",trouve);
 
return 0;
}



Mais, le message suivant n'affiche pas:
printf("valeur de retour %d\n",trouve);
-Pourquoi ?
lorsque je lance l'exécution après la compilation j'ai le message suivant:
HEAP CORRUPTION DETECTED : after normal (#95) at 0*01020068.
CRT detected that the application wrote to memory after end of heap buffer.


Ceci à cause d 'instruction free chaine(); dans la fonction verifier () car je supprime cette instruction donc l'exection se passe.
Mais, comment on va liberer l'espace dynamique louée par chaine[taille] ?
- l'allocation et la libération de l'espace dynamique char *chaine est bien définie ?
- Existe-t-il le type boolean comme un type des données ? comment le déclare ?
- On peut utiliser le type boolean comme valeur de retour pour la fonction verifier() ?

1 réponse

Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
13
Salut,

Heu... C'est quoi ton compilo ? Tu l'as trouvé dans un paquet de lessive ?
Il y a plein de trucs bizarres dans ton code qui n'ont aucune chance de compiler (Par exemple "pFTrie" non déclaré, fopen avec un seul argument).

1) Là :
free(chaine);
fclose(fp);
return 1;

free(chaine);
fclose(fp);
return 0;

Il y a redondance du code d'une part, et d'autre part il est déconseiller d'utiliser deux "return" dans une même fonction. On risque en effet par exemple d'oublier de mettre un fclose aux deux endroits par exemple.

2) Code uniquement en anglais. Ca évite le mélange français/anglais avec les fonctions standards et on a pas de problèmes avec les accents.

3) Tu manipule a la fois des chaînes de taille fixe et des chaînes de taille quelconque. Si tu connais la taille de toutes tes chaînes, tu n'as pas besoin de faire de malloc (Opération couteuse).

4) Dans les fonction type scanf (Contrairement aux fonctions type printf), il faut passer les entier par adresse, de manière à ce que la fonction puisse les affecter.

5) Pas la peine d'initialiser une variable qui est affectée systématiquement plus tard (trouve et objet). Perte de temps à l'exécution.

6) Pourquoi ouvrir le fichier deux fois ? Pourquoi ne pas passer s à "vérifier" ?

7) Il faut tester le retour d'un fopen. Il peut arriver que le fichier soit absent ou impossible à ouvrir.

8) Et finalement, le souci... strlen renvoie la taille de la chaîne sans compter le zéro terminal. Il faut donc allouer une zone de taille + 1. Un tableau de taille n est indicé de 0 à n - 1.

Voilà le source partiellement corrigé :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int verifier(int taille)
{
  FILE *fp;
  char *chaine;
  int i;
  char s[100];
  int objet;
  char attribut[32];
  int nResult;

  nResult = 0;

  /* Initialisation d'une chaîne de taille "taille" avec des '1' */
  chaine = (char*)malloc(taille + 1);
  for(i = 0; i < taille; i++)
    chaine[i] = '1';
  chaine[taille] = '\0';
  printf("chaine   = %s\n", chaine);

  fp = fopen("exemple.txt", "r");
  while (fgets(s, 100, fp))
  {
    sscanf(s, "%d%s", &objet, attribut);
    printf("attribut = %s\n", attribut);
    if (memcmp(attribut, chaine, taille))
      nResult = 1;
  }
  free(chaine);
  fclose(fp);
  return nResult;
}

int main()
{
  FILE *fp;
  char s[100];
  int objet;
  char attribut[32];
  int taille;
  int trouve;

  fp = fopen("exemple.txt", "r");
  while (fgets(s, 100, fp))
    sscanf(s, "%d%s", &objet, attribut);
  taille = strlen(attribut);
  trouve = verifier(taille);
  printf("valeur de retour %d\n", trouve);

  return 0;
}