即使在fclose之后使用valgrind也会出现内存泄漏问题

即使在fclose之后使用valgrind也会出现内存泄漏问题,c,memory-leaks,valgrind,C,Memory Leaks,Valgrind,我的valgrind有问题,问题是这个函数中的内存明显泄漏 void lectureFichier(const char * nomFichier, message ** tete){ message * test=creationCellule(); FILE * fp = fopen(nomFichier, "r"); if(!fp) { perror("fopen failed\n");

我的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的结果:

我找不到问题。你有什么建议吗

下面是包含上述功能的整个代码,当我将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;

}
#包括
#包括
#包括
#包括
#包括“tp1.h”
消息*creationCellule(){
消息*cellle=NULL;
游离(细胞);
cellle=malloc(sizeof(message));
如果(!cellle)
{
perror(“malloc故障”);
退出(退出失败);
}
Cellle->dateDeb=0;
Cellle->dateFin=0;
cellle->suivant=NULL;
memset(cellle->text,'\0',TAILLE_MAX);
返回细胞;
}
/*每一个日期的日期*/
消息*recherche(消息*tete,int-date){
消息**prec=tete;
消息*cour=*tete;
while(cour!=NULL&&cour->dateDebsuivant);
cour=cour->suivant;
}
返回预处理;
}
/*这是一份制作文件*/
无效插入(消息**tete,消息*cellle){
(无效)太特;
(空)细胞;
消息**prec;
如果(单元!=NULL){
prec=记录(太特、赛璐珞->日期);
Cellle->suivant=*prec;
*prec=细胞;
}
} 
/*这是一个很好的例子,它是一个很好的例子*/
无效讲师姓名(const char*nomFichier,message**tete){
message*test=creationcellue();
文件*fp=fopen(nomFichier,“r”);
如果(!fp)
{
perror(“fopen失败\n”);
退出(退出失败);
}
而(fscanf(fp,,%d%d,&(test->dateDeb),&(test->dateFin))==2)
{
如果(fscanf(fp,“%d%d”,&(测试->日期deb),&(测试->日期fin))!=2)
{
fprintf(stderr,前两个的fscanf);
免费(测试);
退出(退出失败);
}
fgets(测试->文本,100,fp);
插入(tete,test);
测试=creationCellule();
}
fclose(fp);
}  
无效附加声明(信息**tete)
{
如果(太特)
{
消息*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;
}
}
}
无效抑制(消息**tete、int valeur、int dateDeb)
{
消息**prec;
prec=重新记录(太特,日期b);
如果((*prec)!=NULL&(*prec)->dateFin==valeur)
{
(*prec)=(*prec)->suivant;
}
}
//练习3
无效供应清单(信息**tete)
{
消息*pt=*tete;
时间;
结构tm*日期;
int intNum;
temps=时间(空);
日期=本地时间(&temps);
字符缓冲区[9];
如果((日期->周一)周日+1900,日期->周一+1,日期->周日);
}
否则{
sprintf(缓冲区,“%d%d%d”,日期->商标年+1900,日期->商标月+1,日期->商标日);
}
intNum=atoi(缓冲区);
while(pt!=NULL)
{
如果((pt->dateFin)文本);
抑制(tete,pt->dateFin,pt->dateDeb);
}
pt=pt->suivant;
}
}
无效更改日期(int-dateChange、int-dateInit、消息**tete)
{
消息*point=*tete;
//printf(“Kjo-eshte-tete%p:\n”,(*点));
while(点!=NULL)
{
如果((点->日期删除)=dateInit)
{                
printf(“%d\n”,point->dateDeb);
printf(“%s\n”,点->文本);
point->dateDeb=dateChange;
}
点=点->suivant;
}
}
int main(int argc,char*argv[])
{
常量字符*name=argv[1];
消息*pointeur=NULL;
//消息**tete=&pointeur;
int dateInit=19973012;
int dateChange=20003008;
讲师(姓名和导师);
供应冷冻剂和针剂;
affichageListe(和pointeur);
while(pointeur)
{
消息*当前=指针;
pointeur=pointeur->suivant;
自由(电流);
}
返回0;
}
您的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);

           }

如果你的问题是内存泄漏,那么你应该对动态分配的指针使用free(fp)。

你是否忘记了
fclose
文件?@Serge no我已经添加了它,它仍然显示相同的问题,然后忽略它。存在不应释放的内部libc缓冲区。@Serge请查看整个代码您的valgrind报告指向内部fopen缓冲区。没有别的了。因此,看起来程序本身没有泄漏。
exit()
关闭打开的stdio文件流。@Shawn我还可以用什么来代替exit(),因为我不允许使用它,但如果我删除它,我会从valgrind那里得到错误?@dbush非常感谢你!!我有一个问题,为什么fscanf会失败,而我会进入if?@MimozaQati,这取决于数据的外观。您连续调用它两次,一次在循环顶部,一次在
if
中,前者被丢弃。您可能不希望在fscanf
fscanf
中出现这种情况,因此如果是这种情况,请使用Mirko的答案。@MimozaQati“仍然可以访问”内存不是错误。
           if(fscanf(fp,"%d %d ",&(test->dateDeb), &(test->dateFin))!=2)
           {
                    fprintf(stderr,"fscanf of first two\n");
                    fclose(fp);
                    free(test);

                    exit(EXIT_FAILURE);

           }