C - 双倍免费

时间:2014-11-30 07:36:35

标签: c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct strqueue {
    struct lnode *front;
    struct lnode *back;
    int length;
};

struct lnode {
    char *item;
    struct lnode *next;
};

StrQueue create_StrQueue(void) {
    struct strqueue *sq = malloc(sizeof(struct strqueue));
    sq->length = 0;
    sq->front = NULL;
    sq->back = NULL;
    return sq;
}

void destroy_nodes(struct lnode *l) {
    while (l!=NULL) {
        struct lnode *c = l;
        l=l->next;
        free(c);
    }
}

void destroy_StrQueue(StrQueue sq) {
    destroy_nodes(sq->front);
    free(sq);
}

void sq_add_back(StrQueue sq, const char *str) {
    struct lnode *n = malloc(sizeof(struct lnode));
    n->item = malloc(sizeof(char)*(strlen(str)+1));
    strcpy(n->item, str);
    n->next = NULL;
    if (sq->length == 0) {
        sq->front = n;
        sq->back = n;
    } else {
        sq->back->next = n;
        sq->back = n;
    }
    sq->length++;
}

char *sq_remove_front(StrQueue sq) {
   if (sq->front == NULL) {
      return NULL;
   } else {
      struct lnode *f = sq->front;
      char *temp = sq->front->item;
      sq->front = sq->front->next;
      sq->length--;
      //Delete the line below will not cause an error of not free all memory
      free(f->item);
      free(f);
      return temp;
   }
}

int sq_length(StrQueue sq) {
    return sq->length;
}

在这里,我想把它作为链表制作,但是当我使用它时,它总是说我试图加倍释放某些东西。我的代码中哪一部分错了?是否存在内存泄漏或内存分配错误?

2 个答案:

答案 0 :(得分:4)

struct lnode *f = sq->front;
char *temp = sq->front->item;
sq->front = sq->front->next;
sq->length--;
//Delete the line below will not cause an error of not free all memory
free(f->item);
free(f);
return temp;

它将指针temp返回到free中的free(f->item) d内存,通过该指针读取字符串是未定义的行为。如果你free那将是双free。基本上,返回的指针是无用的。

修复是避免在该函数中执行free(f->item)。调用者需要在使用后释放指向字符串的指针。


单链表最好用以下表示:

struct lnode *head, **tail;

初始化为:

head = NULL;
tail = &head;

在这种情况下,不需要在附加时对空列表进行特殊处理。追加始终是:

*tail = n;
tail = &n->next;

从正面移除:

struct lnode *n = head;
if(head) {
    head = head->next;
    if(!head) 
        tail = &head;
} 
return n;

答案 1 :(得分:0)

您可以在char *sq_remove_front(StrQueue sq)中尝试此操作:

if (f->item != NULL) {
    free(f->item);
    f->item = NULL;
}
if (f != NULL) {
    free(f);
    sq->front = NULL;
}

它会避免在指针上执行两次free()