2017-07-16 15 views
0

Dieser Code scheint zu funktionieren. Aber ich bin immer Valgrind Fehler mit diesem Code:Warteschlange valgrind Fehler

#include <stdlib.h> 
#include "queue.h" 
#include "queuepriv.h" 
#include <string.h> 

Queue *Queue_init(void) 
{ 
    Queue *q = calloc(1, sizeof(Queue)); 
    return q; 
} 

int Queue_enqueue(Queue *q, const char *id, const char *name) 
{ 
    // implement this function 
    struct student *new = calloc(1, sizeof(struct student)); 
    if (strlen(id) <= 6) { 
     strcpy(new->id, id); 
     new->name = malloc(strlen(name) + 1); 
     strcpy(new->name, name); 
     new->name[strlen(name)] = '\0'; 
     if (q->last) 
     q->last->next = new; 
     q->last = new; 
     q->last->next = NULL; 

     if (!q->first) 
     q->first = q->last; 
     return 1; 
    } else { 
     return 0; 
    } 

} 

char *Queue_firstID(Queue *q) 
{ 
    if (q && q->first) 
     return q->first->id; 
    else 
     return NULL; 
} 

char *Queue_firstName(Queue *q) 
{ 
    if (q && q->first) 
     return q->first->name; 
    else 
     return NULL; 
} 

int Queue_dequeue(Queue *q) 
{ 
    // implement this function 
    if (q->first) { 
     struct student *fst = q->first; 
     struct student *nxt = fst->next; 
     free(fst->name); 
     free(fst); 
     q->first = nxt; 
     if (!q->first) 
     q->last = NULL; 
     return 1; 
    } else { 
     return 0; 
    } 
} 

int Queue_drop(Queue *q, const char *id) 
{ 
    // implement this function 
    struct student *current = q->first; 
    struct student *previous = NULL; 

    while(current) { 
     if (!strcmp(id, current->id)) { 
     if(current == q->first) { 
      q->first = current->next; 
     } else if(current == q->last) { 
      q->last = previous; 
      q->last->next = NULL; 
     } else { 
      previous->next = current->next; 
     } 
     free(current->name); 
     free(current); 
     return 1; 
     } 
     previous = current; 
     current = current->next; 
    } 
    return 0; 
} 

void Queue_delete(Queue *q) 
{ 
    if (q) { 
     while(Queue_dequeue(q)); 
     free(q); 
    } 
} 

Die queuepriv.h:

#ifndef QUEUEPRIV_H 
#define QUEUEPRIV_H 

#include "queue.h" 

/* One student in linked list*/ 
struct student { 
    char id[7]; // student ID: 6 characters + '\0' 
    char *name; // Name of student, allocated dynamically 
    struct student *next; // next student in linked list 
}; 

/* For storing the first and last item in linked list 
* If list is empty, both <first> and <last> are NULL 
* If list has one element, <first> and <last> point to the same place 
*/ 
struct queue { 
    struct student *first; 
    struct student *last; 
}; 

#endif 

Valgrind Ausgang:

==16237== 24 bytes in 1 blocks are definitely lost in loss record 48 of 61 
==16237== at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==16237== by 0x4034F4: Queue_enqueue (queue.c.nomain.c:15) 
==16237== by 0x4021DD: test_Queue_enqueue (test_source.c:104) 
==16237== by 0x407542: srunner_run (in /tmp/user/867402f030a5e9991da6016803cf05863b3e7662e8f00ef3ced1e3ca2e2ded8c/c-kurssi/Module_3/07_queue/test/test) 
==16237== by 0x402E4B: tmc_run_tests (tmc-check.c:122) 
==16237== by 0x402B06: main (test_source.c:226) 
==16237== 
==16238== 24 bytes in 1 blocks are definitely lost in loss record 50 of 64 
==16238== at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==16238== by 0x4034F4: Queue_enqueue (queue.c.nomain.c:15) 
==16238== by 0x402449: test_Queue_dequeue (test_source.c:135) 
==16238== by 0x407542: srunner_run (in /tmp/user/867402f030a5e9991da6016803cf05863b3e7662e8f00ef3ced1e3ca2e2ded8c/c-kurssi/Module_3/07_queue/test/test) 
==16238== by 0x402E4B: tmc_run_tests (tmc-check.c:122) 
==16238== by 0x402B06: main (test_source.c:226) 
==16238== 
==16239== 24 bytes in 1 blocks are definitely lost in loss record 49 of 64 
==16239== at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==16239== by 0x4034F4: Queue_enqueue (queue.c.nomain.c:15) 
==16239== by 0x4027C1: test_Queue_drop (test_source.c:182) 
==16239== by 0x407542: srunner_run (in /tmp/user/867402f030a5e9991da6016803cf05863b3e7662e8f00ef3ced1e3ca2e2ded8c/c-kurssi/Module_3/07_queue/test/test) 
==16239== by 0x402E4B: tmc_run_tests (tmc-check.c:122) 
==16239== by 0x402B06: main (test_source.c:226) 
==16239== 

ich kann nicht herausfinden, wo das ist Speicherleck, weil ich denke, dass ich den gesamten Speicher in den Funktionen zum Herausnehmen und Ablegen freigebe.

Vielen Dank im Voraus.

+0

In Funktion 'Queue_dequeue', was passiert, wenn' q-> first' null ist? Die Anweisung 'struct student * nxt = fst-> next;' schlägt fehl. – tilz0R

+0

Wenn 'q-> first' null ist, sollte es nicht die' struct student * nxt = fst-> next'line ausführen? – Coldcode

+0

Wie ich es verstehe, ist, wenn das 'q-> first' null ist, dann die if-Anweisung 0 und die nächsten Zeilen nicht ausgeführt werden? Ich kann mich irren. – Coldcode

Antwort

2

In diesem Code

int Queue_enqueue(Queue *q, const char *id, const char *name) 
{ 
    // implement this function 
    struct student *new = calloc(1, sizeof(struct student)); 
    if (strlen(id) <= 6) { 
     strcpy(new->id, id); 
     new->name = malloc(strlen(name) + 1); 
     strcpy(new->name, name); 
     new->name[strlen(name)] = '\0'; 
     if (q->last) 
     q->last->next = new; 
     q->last = new; 
     q->last->next = NULL; 

     if (!q->first) 
     q->first = q->last; 
     return 1; 
    } else { 
     return 0; 
    } 

} 

Sie Leck-Speicher, wenn strlen(id) > 6.

In diesem Fall Sie:

int Queue_enqueue(Queue *q, const char *id, const char *name) 
{ 
    // implement this function 
    struct student *new = calloc(1, sizeof(struct student)); 
    if (strlen(id) <= 6) { 
     //don't get in here 
     .... 
    } else { 
     // get in here and leak the memory assigned to new 
     return 0; 
    } 

} 

Vielleicht sollten Sie es ändern:

int Queue_enqueue(Queue *q, const char *id, const char *name) 
{ 
    // implement this function 
    struct student *new = calloc(1, sizeof(struct student)); 
    if (strlen(id) <= 6) { 
     .... 
    } else { 
     free(new); // Free the memory 
     return 0; 
    } 

} 
+0

Oder besser, machen Sie die Kontrolle vor der Zuweisung von Speicher an erster Stelle: 'if (strlen (id)> 6) zurückgeben 0; struct Schüler * new = calloc (1, sizeof (struct Schüler)); ... ' – zwol