Проблемы с утечкой памяти при использовании valgrind даже после fclose - PullRequest
1 голос
/ 10 марта 2019

У меня проблемы с valgrind, проблема в этой функции, где у меня, видимо, есть утечки памяти.

void lectureFichier(const char * nomFichier, message ** tete){

      message * test=creationCellule();

        FILE * fp = fopen(nomFichier, "r");

        if(!fp)
        {

                perror("fopen failed\n");
                exit( EXIT_FAILURE );
        }


        while(fscanf(fp,"%d %d ",&(test->dateDeb), &(test->dateFin))==2)
        {


               if(fscanf(fp,"%d %d ",&(test->dateDeb), &(test->dateFin))!=2)
               {
                        fprintf(stderr,"fscanf of first two\n");
                        free(test);

                        exit(EXIT_FAILURE);

               }

                fgets(test->text,100,fp);
                insertion(tete,test);
                test=creationCellule();

        }
        fclose(fp);
     }

Посмотрите на результат valgrind:

enter image description here

Я не могу найти проблему.Есть ли у вас какие-либо предложения?

ЗДЕСЬ ВСЕ КОД, КОТОРЫЙ СОДЕРЖИТ ФУНКЦИЮ ВЫШЕ, КОГДА Я ИСПОЛЬЗУЮ VALGRIND С ЭТИМ КОДОМ, ЭТО ДАЕТ РЕЗУЛЬТАТ, КАК ПОКАЗАНО НА КАРТИНКЕ ВЫШЕ:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "tp1.h"

message * creationCellule(){

    message * cellule=NULL;
    free(cellule);
    cellule=malloc(sizeof(message));
    if(!cellule)
    {
            perror("malloc failes\n");
            exit(EXIT_FAILURE);
    }


        cellule -> dateDeb = 0;
        cellule -> dateFin = 0;
        cellule -> suivant = NULL;
        memset(cellule->text, '\0', TAILLE_MAX);




    return cellule;
}

/*bejme recherche per date de deb se eshte trie nga date deb*/
message * recherche(message * tete, int date){


    message ** prec = tete;
    message * cour = *tete;

    while( cour != NULL && cour -> dateDeb < date){

        prec = &(cour -> suivant);
        cour = cour -> suivant;

    }

    return prec;

}

/*la prochaine fois il faut venir avec un makefile*/
void insertion(message ** tete, message * cellule){

    (void)tete;
    (void)cellule;

    message ** prec;


    if(cellule != NULL){
            prec = recherche(tete, cellule -> dateDeb);
            cellule -> suivant = *prec;
            *prec = cellule;
    }


} 


/*duhet te lexojme fichier ne fillim dhe kete fichier do e krijojme ne vete*/
void lectureFichier(const char * nomFichier, message ** tete){



    message * test=creationCellule();

        FILE * fp = fopen(nomFichier, "r");



        if(!fp)
        {

                perror("fopen failed\n");
                exit( EXIT_FAILURE );
        }


        while(fscanf(fp,"%d %d ",&(test->dateDeb), &(test->dateFin))==2)
        {


               if(fscanf(fp,"%d %d ",&(test->dateDeb), &(test->dateFin))!=2)
               {
                        fprintf(stderr,"fscanf of first two\n");
                        free(test);

                        exit(EXIT_FAILURE);

               }

                fgets(test->text,100,fp);
                insertion(tete,test);
                test=creationCellule();

        }

                fclose(fp);


     }  




void affichageListe(message ** tete)
{


    if(tete)
    {
        message * tmp = *tete;
        while( tmp )
        {
                //printf("jam ktu\n");
                    printf("DateDeb = %d \n", tmp -> dateDeb);
            printf("DateFin = %d \n", tmp -> dateFin);
            printf("Text = %s \n", tmp -> text);
            tmp = tmp -> suivant;
        }
    }
}



void suppression(message**tete,int valeur,int dateDeb)
{
        message **prec;

        prec=recherche(tete,dateDeb);

        if((*prec)!=NULL && (*prec)->dateFin==valeur)
        {

                (*prec)=(*prec)->suivant;
        }

}

//EXERCICE 3

void supprimeObsoletes(message **tete)
{

        message *pt=*tete;
        time_t temps;
        struct tm *date;
        int intNum;
        temps=time(NULL);
        date=localtime(&temps);

        char buffer[9];
        if((date->tm_mon)<10){
                sprintf(buffer,"%d0%d%d",date->tm_year + 1900,date->tm_mon +1,date->tm_mday);
        }
        else{
                sprintf(buffer,"%d%d%d",date->tm_year + 1900,date->tm_mon +1,date->tm_mday);
        }

        intNum=atoi(buffer);

        while(pt!=NULL)
        {


                if((pt->dateFin)<intNum)
                {

                     printf("KTU HYB %s\n",pt->text);
                        suppression(tete,pt->dateFin,pt->dateDeb);


                }


                pt=pt->suivant;
         }

}


void changeDate(int dateChange, int dateInit,message **tete)
{


        message *point=*tete;
        //printf("Kjo eshte tete %p:\n",(*point));

        while(point!=NULL)
        {

                if((point->dateDeb)==dateInit)
                {                

                        printf("%d\n",point->dateDeb);
                        printf("%s\n",point->text);

                        point->dateDeb=dateChange;


                }

                point=point->suivant;
        }

}


int main(int argc, char * argv[])
{

        const char * name=argv[1];
        message * pointeur = NULL;
    //message ** tete = &pointeur;
        int dateInit=19973012;
        int dateChange=20003008;
        lectureFichier(name, &pointeur);
        supprimeObsoletes(&pointeur);
        affichageListe(&pointeur);

        while(pointeur)
        {


                message *current=pointeur;
                pointeur=pointeur->suivant;
                free(current);


        }
    return 0;

}

Ответы [ 3 ]

2 голосов
/ 10 марта 2019

Ваш журнал valgrind показывает "fscanf первых двух" как часть вывода программы.Эта часть происходит, когда в цикле происходит сбой вызова fscanf.Вы звоните exit, но не закрываете файл.Сначала нужно закрыть файл:

           if(fscanf(fp,"%d %d ",&(test->dateDeb), &(test->dateFin))!=2)
           {
                    fprintf(stderr,"fscanf of first two\n");
                    fclose(fp);
                    free(test);

                    exit(EXIT_FAILURE);

           }
1 голос
/ 10 марта 2019
void lectureFichier(const char * nomFichier, message ** tete)
{
    message * test=creationCellule();

    FILE * fp = fopen(nomFichier, "r");
    if(!fp)
    {
        perror("fopen failed\n");
        exit( EXIT_FAILURE );
    }

    while(fscanf(fp,"%d %d ", &(test->dateDeb), &(test->dateFin))==2)
    {
//        Here you are reading again. That's not what you want.
//        if(fscanf(fp,"%d %d ",&(test->dateDeb), &(test->dateFin))!=2)
//        {
//            fprintf(stderr,"fscanf of first two\n");
//            free(test);
//            exit(EXIT_FAILURE);
//        }
        fgets(test->text,100,fp);
        insertion(tete,test);
        test=creationCellule();
    }
    // Here you can free the last test, because it is not used
    free(test);
    fclose(fp);
}
0 голосов
/ 10 марта 2019

Если ваша проблема связана с утечками памяти, вы должны использовать free (fp) для динамически размещаемых указателей.

...