2017-07-16 105 views
0

此代码似乎工作。但是,我越来越Valgrind的错误与此代码:排队valgrind错误

#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); 
    } 
} 

的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的输出:

==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== 

我想不出哪里是内存泄漏,因为我认为我释放了出列和丢弃功能中的所有内存。

预先感谢您。

+0

在功能'Queue_dequeue'如果'Q-> first'为空会发生什么?语句'struct student * nxt = fst-> next;'失败。 – tilz0R

+0

如果'q-> first'为null,那么它不应该运行'struct student * nxt = fst-> next'line? – Coldcode

+0

我的理解是,如果'q-> first'为null,那么if语句会得到0,并且下一行不会运行?我可能是错的。 – Coldcode

回答

2

在这段代码

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; 
    } 

} 

您泄漏内存时strlen(id) > 6

在这种情况下你:

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; 
    } 

} 

也许你应该将其更改为:

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

或者更好,在分配内存之前先进行检查:'if(strlen(id)> 6)return 0; struct student * new = calloc(1,sizeof(struct student)); ...' – zwol