即使在fclose之后使用valgrind也会出现内存泄漏问题
我的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");
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
中,前者被丢弃。您可能不希望在fscanffscanf
中出现这种情况,因此如果是这种情况,请使用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);
}