2016-04-01 8 views
0

Ich implementierte eine einfache Version von ls namens myls, und wenn ich versuche, die im Programm erstellte verkettete Liste zu befreien, bekomme ich ungültige freie() Nachricht, ich denke, es hat etwas zu tun mit closedir(), aber ich weiß nicht genau, warum, hier ist die Speicherleckprüfung:Ungültige freie() nach closedir()

#include <stdio.h> 
#include <dirent.h> 
#include <stdlib.h> 
#include <string.h> 
typedef struct n{ 
    char *key; 
    struct n *next; 
} node; 
node *list = NULL; 

// errorCheck(*myDir) -- check if the target directory is opened 
// correctly or print out an error message if not and exit. 
void errorCheck(DIR *myDir){ 
    if (myDir == NULL){ 
     perror("Error"); 
     exit(1); 
    } 
} 

// buildList(*myDir) -- create a list containing 
// all directories' name. 
node *buildList(DIR *myDir){ 
    struct dirent *dirPtr; 
    node *temp = NULL; 

    // put into list 
    while ((dirPtr = readdir(myDir)) != NULL){ 
     temp = malloc(sizeof(node)); 
     if (temp == NULL){ 
      fprintf(stderr, "Error: out of memory!\n"); 
      exit(1); 
     } 
     temp -> key = dirPtr -> d_name; 
     temp -> next = list; 
     list = temp; 
    } 

    return temp; 
} 

// printList(*list) -- print out the linked list. 
void printList(node *list){ 
    node *temp = NULL; 

    temp = list; 
    while (temp != NULL){ 
     printf("%s\n", temp -> key); 
     temp = temp -> next; 
    } 
} 

// swap(*n1, *n2) -- swap keys of these two nodes. 
void swap(node *n1, node *n2){ 
    char *temp; 
    temp = n1 -> key; 
    n1 -> key = n2 -> key; 
    n2 -> key = temp; 
} 

// sortList(*list) -- use bubble sort to sort the 
// linked list in alphabetic order. 
void sortList(node *list){ 
    node *curr, *last = NULL; 
    int changed; 

    do{ 
     changed = 0; 
     curr = list; 

     while (curr -> next != last){ 
      if (strcmp(curr -> key, curr -> next -> key) > 0){ 
       swap(curr, curr -> next); 
       changed = 1; 
      } 
      curr = curr -> next; 
     } 
     last = curr; 
    } while (changed == 1); 
} 

// freeList() -- free up the linked list. 
void freeList(){ 
    node *temp = list; 

    while (list != NULL){ 
     temp = list; 
     list = list -> next; 
     free(temp -> key); 
     free(temp); 
    } 
} 

// main() -- main structure of the program 
int main(int argc, char *argv[]){ 
    DIR *myDir; 

    if (argc == 1){ 
     myDir = opendir("."); 
     errorCheck(myDir); 
     list = buildList(myDir); 
     sortList(list); 
     printList(list); 
     closedir(myDir); 
    } 
    else if(argc == 2){ 
     myDir = opendir(argv[1]); 
     errorCheck(myDir); 
     list = buildList(myDir); 
     sortList(list); 
     printList(list); 
     closedir(myDir); 
    } 
    else{ 
     fprintf(stderr, "Error: too many arguments!\n"); 
     return 1; 
    } 

    freeList(); 
    return 0; 
} 
:

******:~/***/***/myls$ valgrind --leak-check=full --show-reachable=yes myls 
==742== Memcheck, a memory error detector 
==742== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al. 
==742== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info 
==742== Command: myls 
==742== 
. 
.. 
Makefile 
myls 
myls.c 
tests 
==742== Invalid free()/delete/delete[]/realloc() 
==742== at 0x4C2A82E: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==742== by 0x4009D2: freeList (in /p2/hh/***/***/***/myls/myls) 
==742== by 0x400AE2: main (in /p2/hh/***/***/***/myls/myls) 
==742== Address 0x51f0083 is 67 bytes inside a block of size 32,816 alloc'd 
==742== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==742== by 0x4EECD5A: __alloc_dir (opendir.c:202) 
==742== by 0x400A0B: main (in /p2/hh/***/***/***/myls/myls) 
==742== 
==742== 
==742== HEAP SUMMARY: 
==742==  in use at exit: 0 bytes in 0 blocks 
==742== total heap usage: 7 allocs, 13 frees, 32,912 bytes allocated 
==742== 
==742== All heap blocks were freed -- no leaks are possible 
==742== 
==742== For counts of detected and suppressed errors, rerun with: -v 
==742== ERROR SUMMARY: 6 errors from 1 contexts (suppressed: 2 from 2) 

und hier ist mein Code (*** Daten angibt)

Kann jemand helfen?

+3

Diese 'Temp -> key = dirPtr -> d_name;' sollten eine Kopie 'strdup' oder die' malloc' Route werden zu machen. Benutze 'MAX_PATH_LEN' in deiner Struktur und mach' strcpy'. –

+0

Oh mein Gott, das ist die Lösung und ich habe es vermisst, vielen Dank! – Crysishy

+0

Kein Problem - ich sehe nur aus wie ein Gott :-) –

Antwort

0

Ich sehe nicht, wo die Speicherzuweisung für temp-> Schlüssel explizit, so meine Vermutung ist, dass Sie nicht frei() darauf aufrufen sollten.

// freeList() -- free up the linked list. 
void freeList(){ 
    node *temp = list; 

    while (list != NULL){ 
     temp = list; 
     list = list -> next; 
     **free(temp -> key);** 
     free(temp); 
    } 

Info ab: http://man7.org/linux/man-pages/man3/readdir.3.html

On success, readdir() returns a pointer to a dirent structure. (This 
    structure may be statically allocated; do not attempt to free(3) it.) 
+0

Vielleicht sollten Sie den Kommentar lesen, die ich vor 12 Minuten gemacht habe und schlagen eine Lösung mit dieser Information –

+0

@ ed-heal, ich war in das Problem zu sehen, wo das Problem ist, was die Problemstellung ist (und nicht die Lösung selbst). Es könnte sein, dass deine Kommentare sich mit meinen gekreuzt haben, bevor ich weiter nachgesehen habe. Ja, die Lösung ist dann zu sehen, was im Code fehlt, um es zum Laufen zu bringen - standup(), strip(), malloc() + strlcpy()/strcpy() usw. Also versuche nicht, sarkastisch zu sein Ihre Kommentare oder Antworten. – Ravi

+0

@ ed-heal, vielleicht könntest du schreiben: "Ich habe gerade Kommentare gepostet, was ich denke, das Problem ist, du könntest dich darauf beziehen". Wie klingt das zur Abwechslung? – Ravi