我遇到内存泄漏问题(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输出:
函数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;
}
}
}
}
以下提议的代码:
现在,建议的代码:
#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;
}