使用valgrind的循环中的malloc

问题描述 投票:1回答:2

我遇到内存泄漏问题(valgrind检测到错误)。

所以这是我的第一个功能:

message *creationCellule() {
    message *cellule;
    cellule = (message *)malloc(sizeof(message));

    if (cellule != NULL) {
        cellule->dateDeb = 0;
        cellule->dateFin = 0;
        cellule->suivant = NULL;
        memset(cellule->text, '\0', TAILLE_MAX);
    }
    return cellule;
}

它返回由malloc分配的cellule。

现在我有这个:

void lectureFichier(const char *nomFichier, message **tete) {
    FILE *fp = fopen(nomFichier, "r");
    message *test;
    test = creationCellule();
    int k = 0;

    if (fp != NULL) {
        k = fscanf(fp, "%d %d ", &(test->dateDeb), &(test->dateFin));

        while (k != EOF) {
            fgets(test->text, 100, fp);

            insertion(tete, test);
            test = creationCellule();

            k = fscanf(fp,"%d %d ", &(test->dateDeb), &(test->dateFin));
        }
    }
}

我在一个循环中调用creationCellule()

我的问题是,如果我把free(test)放在循环中,我会丢失我的代码的所有上下文,valgrind显示我ERROR SUMMARY:213 errors from 19 contexts.

我该怎么办 ?

这是完整的代码和valgrind输出:

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

message *creationCellule() {
    message *cellule;
    cellule = (message *)malloc(sizeof(message));

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

    return cellule;
}

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;
}

void insertion(message **tete, message *cellule) {
    message **prec;

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

void lectureFichier(const char *nomFichier, message **tete) {
    FILE *fp = fopen(nomFichier, "r");
    message *test;
    test = creationCellule();
    int k = 0;

    if (fp != NULL) {
        k = fscanf(fp,"%d %d ", &(test->dateDeb), &(test->dateFin));

        while (k != EOF) {
            fgets(test->text, 100, fp);

            insertion(tete, test);
            test = creationCellule();

            k = fscanf(fp,"%d %d ", &(test->dateDeb), &(test->dateFin));
        }
    }
}

void affichageListe(message **tete) {
    if (tete != NULL) {
        message *tmp = *tete;
        while (tmp != NULL) {
            //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);

    //printf("Prec text: %s , prec dateFin: %d\n", (*prec)->text, (*prec)->dateFin);

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

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;

    FILE *fp = fopen(name, "r");
    lectureFichier(name, tete);
    //changeDate(dateChange, dateInit, tete);

    supprimeObsoletes(tete);

    affichageListe(tete);

    return 0;
}

标题:tp1.h

#ifndef TP1_TEST_H
#define TP1_TEST_H

#define TAILLE_MAX 100

typedef struct cell {
    int dateDeb;
    int dateFin;
    char text[TAILLE_MAX];
    struct cell *suivant;
} message;

message *creationCellule();
message **recherche(message **tete, int date);
void affichageListe(message **tete);
void insertion(message **tete, message *cellule);
void lectureFichier(const char * nomFichier, message **tete);

.txt文件(在执行中添加)

19973012 20220512 TEXT 1
19980511 19001203 THIS
20011102 20301123 HOUSE
20020809 20301025 HELP

Valgrind输出:

Valgrind output

c valgrind
2个回答
1
投票

函数lectureFichier不会正确释放未使用的节点。

这是一个更正版本:

void lectureFichier(const char *nomFichier, message **tete) {
    FILE *fp = fopen(nomFichier, "r");

    if (fp != NULL) {
        for (;;) {
            message *node = creationCellule();
            if (fscanf(fp, "%d%d %99s", &node->dateDeb, &node->dateFin, node->text) == 3) {
                insertion(tete, node);
            } else {
                free(node);
                break;
            }
        }
    }
}

0
投票

以下提议的代码:

  1. 干净利落地编译
  2. 妥善处理错误
  3. 删除未使用的代码
  4. 发生错误时不会清除链接列表 - 您需要添加它

现在,建议的代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>



#ifndef TP1_TEST_H
#define TP1_TEST_H

#define TAILLE_MAX 100

struct cell
{
    int dateDeb;
    int dateFin;
    char text[TAILLE_MAX];
    struct cell * suivant;
};
typedef struct cell message;


message * creationCellule( void );
message ** recherche(      message ** tete, int date );
void      affichageListe(  message ** tete );
FILE *    ecrireFichier(   message ** tete );
void      dateNonExpires(  message ** tete );
#endif // TPI_TEST_H




message * creationCellule()
{
    message * cellule = malloc(sizeof(message));
    if( !cellule )
    {
        perror( "malloc failed" );
        exit( EXIT_FAILURE );
    }

    cellule->dateDeb = 0;
    cellule->dateFin = 0;
    cellule->suivant = NULL;
    return cellule;
}


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;
}


void insertion(message ** tete, message * cellule)
{
    (void)tete;
    (void)cellule;
    // insert code that does something reasonable
} 


void lectureFichier(const char * nomFichier, message ** tete)
{   
    FILE * fp = fopen(nomFichier, "r");
    if( !fp )
    {
        perror( "fopen failed" );
        exit( EXIT_FAILURE );   
    }

    test = creationCellule();

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

        insertion(tete, test);
        test = creationCellule();
    }
}


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 );
    //printf("Prec text: %s , prec dateFin: %d\n",(*prec)->text,(*prec)->dateFin);

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


void supprimeObsoletes(message **tete)
{
    message *pt = *tete;

    time_t temps;
    struct tm *date;

    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);
    }

    int intNum=atoi(buffer);

    while( pt )
    {
        if( (pt->dateFin) < intNum )
        {
            printf( "KTU HYB %s\n", pt->text );
            suppression( tete, pt->dateFin, pt->dateDeb );
        }

        pt=pt->suivant;
    }
}



int main(int argc, char * argv[])
{
    if( argc != 2 )
    {
        fprintf( stderr, "USAGE: %s filename\n", argv[0] );
        exit( EXIT_FAILURE );
    }

    const char * name  = argv[1];
    message * pointeur = NULL;

    lectureFichier( name, &pointeur );
    supprimeObsoletes(    &pointeur );
    affichageListe(       &pointeur );

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

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.