valgrind的c快速排序内存泄漏
我在初始化这个c快速排序代码的内存时遇到了一个问题。 排序算法工作正常。 我唯一的问题是释放内存 这是我的密码:valgrind的c快速排序内存泄漏,c,list,memory-leaks,quicksort,heap-memory,C,List,Memory Leaks,Quicksort,Heap Memory,我在初始化这个c快速排序代码的内存时遇到了一个问题。 排序算法工作正常。 我唯一的问题是释放内存 这是我的密码: #define _POSIX_C_SOURCE 200809L #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include "quicksort.h" /*********************************
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "quicksort.h"
/*****************************************************
* Die benoetigten structs findet Ihr in quicksort.h *
*****************************************************/
void init_list(list* mylist)
{
// HIER Liste initialisieren
mylist->first=NULL;
mylist->last=NULL;
}
// Diese Funktion fügt Listenelemente an die Liste an
void insert_list(list_element* le, list* mylist)
{
// HIER Code einfügen
if (mylist->first == NULL) {
le->next = NULL;
mylist->first = le;
mylist->last = le;
}
else {
le->next = mylist->first;
mylist->first = le;
}
}
// Speicher für Listenelemente wieder freigeben
void free_list(list* mylist)
{
// HIER Code einfügen
list_element *current = mylist->first;
list_element *alt;
while (current != NULL) {
alt = current;
current = current->next;
free (alt);
}
free (current);
}
// Namen, Zahlen Paare in Liste einlesen
void read_data(char* filename, list* mylist)
{
// HIER Code einfügen:
// * Speicher allozieren
// * Daten in list_element einlesen
// * insert_front benutzen um list_element in Liste einzufügen
FILE *fprint = fopen(filename, "r");
if (fprint == NULL){
perror("input file könnte nicht geöffnet werden!");
}
while (1){
char buffer[100];
int counter ;
int return_fscanf = fscanf (fprint ,"%s %d",buffer,&counter);
if (return_fscanf == EOF){
break;
}
if (return_fscanf != 2){
printf ("Datei hat ungültiges Format.\n");
break;
}
list_element *new_elem = malloc (sizeof (list_element));
new_elem->password = malloc (sizeof (char)*strlen(buffer)+1);
new_elem->count= counter;
strncpy(new_elem->password, buffer,strlen(buffer));
new_elem->next = NULL;
insert_list (new_elem , mylist );
}
}
// Liste teilen. Teillisten werden in left und right zurück gegeben
list_element* partition( list* input, list* left, list* right )
{
// HIER Code einfügen:
// parition() Funktion implementieren
list_element* pivot=input->first;
init_list(left);
init_list(right);
list_element* t=input->first->next;
while(t!=NULL)
{
list_element* tnext=t->next;
if((t->count) < (pivot->count))
{
insert_list(t,left);
}
else
{
insert_list(t,right);
}
t=tnext;
}
return pivot;
}
// Hauptfunktion des quicksort Algorithmus
void qsort_list(list* mylist)
{
// HIER Code einfügen
if(mylist->first == mylist->last) {
}else{
list LFT;
list RGT;
list* left=&LFT;
list* right=&RGT;
list_element* pivot = partition(mylist, left, right);
qsort_list(left);
qsort_list(right);
if(left->first == NULL){
mylist->first = pivot;
}else{
mylist->first = left->first;
left->last->next = pivot;
}
if(right->first == NULL){
pivot->next = 0;
mylist->last = pivot;
}else{
pivot->next = right->first;
mylist->last = right->last;
}
}
}
// Liste ausgeben
void print_list(list* mylist)
{
// HIER Code einfügen:
// * Laufe über die list_element in mylist und gebe sie aus.
list_element *elem = mylist->first;
while (elem != NULL) {
printf("Passwort : %-15s Haeufigkeit : %-15d\n", elem->password ,
elem->count);
elem = elem->next;
}
printf("\n");
}
这是valgrind报告,泄漏检查=完整:
==244== HEAP SUMMARY:
==244== in use at exit: 1,343 bytes in 101 blocks
==244== total heap usage: 203 allocs, 102 frees, 4,767 bytes allocated
==244==
==244== 791 bytes in 100 blocks are definitely lost in loss record 2 of 2
==244== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==244== by 0x4009D3: read_data (in /mnt/c/Users/YOGA/Desktop/introprog-wise1718/Aufgaben/Blatt10/Vorgaben/quicksort)
==244== by 0x400CBD: main (in /mnt/c/Users/YOGA/Desktop/introprog-wise1718/Aufgaben/Blatt10/Vorgaben/quicksort)
==244==
==244== LEAK SUMMARY:
==244== definitely lost: 791 bytes in 100 blocks
==244== indirectly lost: 0 bytes in 0 blocks
==244== possibly lost: 0 bytes in 0 blocks
==244== still reachable: 552 bytes in 1 blocks
==244== suppressed: 0 bytes in 0 blocks
==244== Reachable blocks (those to which a pointer was found) are not shown.
==244== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==244==
==244== For counts of detected and suppressed errors, rerun with: -v
==244== Use --track-origins=yes to see where uninitialised values come from
==244== ERROR SUMMARY: 101 errors from 2 contexts (suppressed: 0 from 0)
编辑:我把漏洞修好了。我将保持原始代码未经编辑,以便读者可以看到更改
我编辑了void free_列表,但仍然有一个由fopen命令引起的泄漏,该命令需要在void read_数据的末尾使用fclose命令
void free_list(list* mylist)
{
// HIER Code einfügen
list_element *current = mylist->first;
list_element *alt=NULL;
while (current) {
alt = current;
current = current->next;
free(alt->password);
free (alt);
}
}
问题是,您通过malloc在两行中分配内存,但并没有在以后释放所有内存
从我所看到的情况来看,您缺少一个对应的malloc new_elem->password=malloc sizeof char*strlenbuffer+1;。。。但是我的C++是生锈的,所以我可能漏掉了一个。< /p> < p>我看到FFOND的调用,但没有FSEND的调用。也许这就是你的漏洞?ooh这是一个很好的漏洞,是的,保持句柄打开会在内核句柄中产生漏洞好的建议!!我试过了,但它对程序没有任何影响相同的结果和相同数量的泄漏看起来更像是一个评论而不是一个答案。不幸的是,它不允许评论名声不好的问题…valgrind给了你答案:内存泄漏在malloc,在read_数据中。我能知道你是怎么编译的吗?因为如果您使用更高级别的调试进行编译,您现在可以精确地找到与内存泄漏对应的行。无论如何,你需要在你的malloc之后获得自由!!我所有清空malloc的尝试都会返回结果,无论是没有泄漏但看起来很时髦的结果,还是正确的结果但仍然有201个泄漏。有没有更清晰的关于如何免费的建议?我使用gcc-std=c99-Wall来编译,使用valgrind-leak-check=full进行泄漏检查?谁告诉你我们很棒的?!嗨,LazerDance,Valgrind从不撒谎。在我看来,这是最好的利克斯工具之一。没错!!!我试图清空new_elem->password,但每次尝试都会彻底清除结果中的密码列表,或者出现相同数量的泄漏。还有更详细的建议吗?我很欣赏一个如何清空密码部分的分配内存的例子。如果是这样的话,那么你不就是在使用完之前释放内存吗?完全同意!!有没有建议我应该在哪里释放内存?很抱歉,我的c背景只有3个月大。删除自由电流;在函数void free_listlist*mylist中。你不需要释放空指针,我已经释放了。这不会改变任何事情。我仍然有相同数量的泄漏。
void free_list(list* mylist)
{
// HIER Code einfügen
list_element *current = mylist->first;
list_element *alt=NULL;
while (current) {
alt = current;
current = current->next;
free(alt->password);
free (alt);
}
}