首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C- double free

C- double free
EN

Stack Overflow用户
提问于 2014-11-30 15:36:35
回答 2查看 143关注 0票数 0
代码语言:javascript
复制
#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;
}

这里我想让strqueue看起来像一个链表,但是当我使用它的时候,它总是说我试图双重释放一些东西。我的代码的哪一部分是错误的?是否存在内存泄漏或内存分配方面的问题?

EN

回答 2

Stack Overflow用户

发布于 2014-11-30 15:44:35

在……里面

代码语言:javascript
复制
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;

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

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

单链表最好的表示方法是:

代码语言:javascript
复制
struct lnode *head, **tail;

初始化为:

代码语言:javascript
复制
head = NULL;
tail = &head;

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

代码语言:javascript
复制
*tail = n;
tail = &n->next;

从前面删除的是:

代码语言:javascript
复制
struct lnode *n = head;
if(head) {
    head = head->next;
    if(!head) 
        tail = &head;
} 
return n;
票数 4
EN

Stack Overflow用户

发布于 2014-11-30 15:50:02

你可以在char *sq_remove_front(StrQueue sq)中尝试这样做:

代码语言:javascript
复制
if (f->item != NULL) {
    free(f->item);
    f->item = NULL;
}
if (f != NULL) {
    free(f);
    sq->front = NULL;
}

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27211097

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档