按照人的建议释放内存会在 valgrind 中产生错误
Freeing memory as man suggests yields errors in valgrind
我正在尝试释放像这样初始化的结构
MemFile *file = (MemFile *) safe_malloc(sizeof(MemFile));
char *fileMemory = NULL;
FILE *tmp = open_memstream(&fileMemory,&(file->usedMem));
file->fp = tmp;
file->buffer = fileMemory;
file->addbuffer = &fileMemory;
file->addfp = &tmp;
file->isOpen = 1;
file->next = NULL;
file->usedMem = 0;
file->pathname = (char *) safe_malloc((strlen(pathname)+1) * sizeof(char))
但是 valgrind,当我试图释放我的记忆时,吐出
==7958== Invalid write of size 8
==7958== at 0x49118C8: _IO_mem_finish (memstream.c:131)
==7958== by 0x4907FC0: fclose@@GLIBC_2.2.5 (iofclose.c:57)
==7958== by 0x10B5B0: freeFile (mem.c:419)
==7958== by 0x10B32E: mem_remove (mem.c:367)
==7958== by 0x10B678: mem_removeFile (mem.c:441)
==7958== by 0x10B61D: freeMemory (mem.c:431)
==7958== by 0x10D472: main (newserver.c:458)
==7958== Address 0x5677cd0 is in a rw- anonymous segment
==7958==
==7958== Invalid read of size 8
==7958== at 0x49118D2: _IO_mem_finish (memstream.c:133)
==7958== by 0x4907FC0: fclose@@GLIBC_2.2.5 (iofclose.c:57)
==7958== by 0x10B5B0: freeFile (mem.c:419)
==7958== by 0x10B32E: mem_remove (mem.c:367)
==7958== by 0x10B678: mem_removeFile (mem.c:441)
==7958== by 0x10B61D: freeMemory (mem.c:431)
==7958== by 0x10D472: main (newserver.c:458)
==7958== Address 0x5677cd0 is in a rw- anonymous segment
==7958==
==7958== Invalid free() / delete / delete[] / realloc()
==7958== at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==7958== by 0x10B5D8: freeFile (mem.c:422)
==7958== by 0x10B32E: mem_remove (mem.c:367)
==7958== by 0x10B678: mem_removeFile (mem.c:441)
==7958== by 0x10B61D: freeMemory (mem.c:431)
==7958== by 0x10D472: main (newserver.c:458)
==7958== Address 0x4a7a788 is 8 bytes inside a block of size 104 alloc'd
==7958== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==7958== by 0x10E13F: safe_malloc (utils.c:7)
==7958== by 0x10AADC: mem_createFile (mem.c:108)
==7958== by 0x10BC33: doJob (newserver.c:71)
==7958== by 0x10CC26: worker (newserver.c:298)
==7958== by 0x4869608: start_thread (pthread_create.c:477)
==7958== by 0x49A5292: clone (clone.S:95)
==7958==
Exiting==7958==
==7958== HEAP SUMMARY:
==7958== in use at exit: 42 bytes in 1 blocks
==7958== total heap usage: 46 allocs, 46 frees, 27,179 bytes allocated
==7958==
==7958== 42 bytes in 1 blocks are definitely lost in loss record 1 of 1
==7958== at 0x483DFAF: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==7958== by 0x49118C7: _IO_mem_finish (memstream.c:131)
==7958== by 0x4907FC0: fclose@@GLIBC_2.2.5 (iofclose.c:57)
==7958== by 0x10B5B0: freeFile (mem.c:419)
==7958== by 0x10B32E: mem_remove (mem.c:367)
==7958== by 0x10B678: mem_removeFile (mem.c:441)
==7958== by 0x10B61D: freeMemory (mem.c:431)
==7958== by 0x10D472: main (newserver.c:458)
==7958==
==7958== LEAK SUMMARY:
==7958== definitely lost: 42 bytes in 1 blocks
==7958== indirectly lost: 0 bytes in 0 blocks
==7958== possibly lost: 0 bytes in 0 blocks
==7958== still reachable: 0 bytes in 0 blocks
==7958== suppressed: 0 bytes in 0 blocks
==7958==
==7958== For lists of detected and suppressed errors, rerun with: -s
==7958== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
我确实已经尝试了所有方法,我什至必须消除所有内存泄漏,但仍然有无效的读取和写入。已经一个多星期了,我刚刚因为纯粹的愤怒而打破了我的办公桌。
这是释放结构元素的函数
int freeFile(MemFile *file){
if (file == NULL){
return -1;
}
freeifalloc(file->pathname);
if(file->fp != NULL){
fclose(file->fp);
file->fp = NULL;
}
freeifalloc(&(file->buffer));
//freeifalloc(file->fp->_IO_buf_base);
//pthread_mutex_destroy(&(file->fileLock));
freeifalloc(file);
return 1;
}
发送帮助。
内存文件结构
typedef struct fl{
FILE *fp;
char *buffer;
char **addbuffer;
FILE **addfp;
char *pathname;
size_t usedMem;
int isOpen;
struct fl *next;
pthread_mutex_t fileLock;
}MemFile;
freeifalloc
#define freeifalloc(pointer) if(pointer != NULL) {free(pointer); pointer == NULL;}
临时变量是不必要的,是您问题的根源。
//first, allocate your struct
MemFile *file = (MemFile *) safe_malloc(sizeof(MemFile));
//if (!file) error
//you have to zero it out, because in case of an error,
//you probably call the free function, therefore
//the (pointer) fields have to point to NULL
memset(file, 0, sizeof(MemFile));
file->fp = open_memstream(&file->buffer, &file->usedMem);
//if (!file->fp) error
file->addBuffer = &file->buffer; //what is addBuffer, is this really necessary?
file->addfp = &file->fp; //same here, why?
file->isOpen = 1;
file->next = NULL;
//usedMem is set by open_memstream
//file->usedMem = 0;
//this is also different from your statement
//sizeof(char) equals per standard to 1
file->pathname = (char*) safe_malloc(strlen(pathname)+1);
//there is no no need to set the pointer to NULL
//you free the file anyway, so what's the point?
#define freeifalloc(pointer) if (pointer) free(pointer)
// isn't this much cleaner?
int freeFile(MemFile *file){
if (!file)
return -1;
if (file->pathname)
free(file->pathname);
if (file->fp)
fclose(file->fp);
if (file->buffer)
free(file->buffer);
if (file)
free(file);
return 1;
}
我正在尝试释放像这样初始化的结构
MemFile *file = (MemFile *) safe_malloc(sizeof(MemFile));
char *fileMemory = NULL;
FILE *tmp = open_memstream(&fileMemory,&(file->usedMem));
file->fp = tmp;
file->buffer = fileMemory;
file->addbuffer = &fileMemory;
file->addfp = &tmp;
file->isOpen = 1;
file->next = NULL;
file->usedMem = 0;
file->pathname = (char *) safe_malloc((strlen(pathname)+1) * sizeof(char))
但是 valgrind,当我试图释放我的记忆时,吐出
==7958== Invalid write of size 8
==7958== at 0x49118C8: _IO_mem_finish (memstream.c:131)
==7958== by 0x4907FC0: fclose@@GLIBC_2.2.5 (iofclose.c:57)
==7958== by 0x10B5B0: freeFile (mem.c:419)
==7958== by 0x10B32E: mem_remove (mem.c:367)
==7958== by 0x10B678: mem_removeFile (mem.c:441)
==7958== by 0x10B61D: freeMemory (mem.c:431)
==7958== by 0x10D472: main (newserver.c:458)
==7958== Address 0x5677cd0 is in a rw- anonymous segment
==7958==
==7958== Invalid read of size 8
==7958== at 0x49118D2: _IO_mem_finish (memstream.c:133)
==7958== by 0x4907FC0: fclose@@GLIBC_2.2.5 (iofclose.c:57)
==7958== by 0x10B5B0: freeFile (mem.c:419)
==7958== by 0x10B32E: mem_remove (mem.c:367)
==7958== by 0x10B678: mem_removeFile (mem.c:441)
==7958== by 0x10B61D: freeMemory (mem.c:431)
==7958== by 0x10D472: main (newserver.c:458)
==7958== Address 0x5677cd0 is in a rw- anonymous segment
==7958==
==7958== Invalid free() / delete / delete[] / realloc()
==7958== at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==7958== by 0x10B5D8: freeFile (mem.c:422)
==7958== by 0x10B32E: mem_remove (mem.c:367)
==7958== by 0x10B678: mem_removeFile (mem.c:441)
==7958== by 0x10B61D: freeMemory (mem.c:431)
==7958== by 0x10D472: main (newserver.c:458)
==7958== Address 0x4a7a788 is 8 bytes inside a block of size 104 alloc'd
==7958== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==7958== by 0x10E13F: safe_malloc (utils.c:7)
==7958== by 0x10AADC: mem_createFile (mem.c:108)
==7958== by 0x10BC33: doJob (newserver.c:71)
==7958== by 0x10CC26: worker (newserver.c:298)
==7958== by 0x4869608: start_thread (pthread_create.c:477)
==7958== by 0x49A5292: clone (clone.S:95)
==7958==
Exiting==7958==
==7958== HEAP SUMMARY:
==7958== in use at exit: 42 bytes in 1 blocks
==7958== total heap usage: 46 allocs, 46 frees, 27,179 bytes allocated
==7958==
==7958== 42 bytes in 1 blocks are definitely lost in loss record 1 of 1
==7958== at 0x483DFAF: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==7958== by 0x49118C7: _IO_mem_finish (memstream.c:131)
==7958== by 0x4907FC0: fclose@@GLIBC_2.2.5 (iofclose.c:57)
==7958== by 0x10B5B0: freeFile (mem.c:419)
==7958== by 0x10B32E: mem_remove (mem.c:367)
==7958== by 0x10B678: mem_removeFile (mem.c:441)
==7958== by 0x10B61D: freeMemory (mem.c:431)
==7958== by 0x10D472: main (newserver.c:458)
==7958==
==7958== LEAK SUMMARY:
==7958== definitely lost: 42 bytes in 1 blocks
==7958== indirectly lost: 0 bytes in 0 blocks
==7958== possibly lost: 0 bytes in 0 blocks
==7958== still reachable: 0 bytes in 0 blocks
==7958== suppressed: 0 bytes in 0 blocks
==7958==
==7958== For lists of detected and suppressed errors, rerun with: -s
==7958== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
我确实已经尝试了所有方法,我什至必须消除所有内存泄漏,但仍然有无效的读取和写入。已经一个多星期了,我刚刚因为纯粹的愤怒而打破了我的办公桌。 这是释放结构元素的函数
int freeFile(MemFile *file){
if (file == NULL){
return -1;
}
freeifalloc(file->pathname);
if(file->fp != NULL){
fclose(file->fp);
file->fp = NULL;
}
freeifalloc(&(file->buffer));
//freeifalloc(file->fp->_IO_buf_base);
//pthread_mutex_destroy(&(file->fileLock));
freeifalloc(file);
return 1;
}
发送帮助。
内存文件结构
typedef struct fl{
FILE *fp;
char *buffer;
char **addbuffer;
FILE **addfp;
char *pathname;
size_t usedMem;
int isOpen;
struct fl *next;
pthread_mutex_t fileLock;
}MemFile;
freeifalloc
#define freeifalloc(pointer) if(pointer != NULL) {free(pointer); pointer == NULL;}
临时变量是不必要的,是您问题的根源。
//first, allocate your struct
MemFile *file = (MemFile *) safe_malloc(sizeof(MemFile));
//if (!file) error
//you have to zero it out, because in case of an error,
//you probably call the free function, therefore
//the (pointer) fields have to point to NULL
memset(file, 0, sizeof(MemFile));
file->fp = open_memstream(&file->buffer, &file->usedMem);
//if (!file->fp) error
file->addBuffer = &file->buffer; //what is addBuffer, is this really necessary?
file->addfp = &file->fp; //same here, why?
file->isOpen = 1;
file->next = NULL;
//usedMem is set by open_memstream
//file->usedMem = 0;
//this is also different from your statement
//sizeof(char) equals per standard to 1
file->pathname = (char*) safe_malloc(strlen(pathname)+1);
//there is no no need to set the pointer to NULL
//you free the file anyway, so what's the point?
#define freeifalloc(pointer) if (pointer) free(pointer)
// isn't this much cleaner?
int freeFile(MemFile *file){
if (!file)
return -1;
if (file->pathname)
free(file->pathname);
if (file->fp)
fclose(file->fp);
if (file->buffer)
free(file->buffer);
if (file)
free(file);
return 1;
}