【问题标题】:I freed everything but memory is leaking我释放了一切,但内存泄漏
【发布时间】:2015-12-26 09:34:24
【问题描述】:

根据valgrind的说法,这个基本上是在初始化一个struct的函数就是泄漏源:

Item* InitializeItem(char* name, int reg, char* adress)
{
    Item* i = (Item*)malloc(sizeof(Item));

    int a = strlen(name) + 1;
    int b = strlen(adress) + 1;

    i->name = (char*)malloc(a*sizeof(char));
    strcpy(i->name, name);

    i->reg = reg;

    i->adress = (char*)malloc(b*sizeof(char));
    strcpy(i->adress, adress);

    return i;
}

这里是免费功能:

List* Free_List(List* list)
{
    Node* new;
    new = list->First;

    while (new != NULL)
    {
        Node* aux = new->prox;
        free(new->item->name);
        free(new->item->adress);
        free(new->item);
        free(new);
        new = aux;
    }

    free(list);
}

我尝试了所有方法,但我不明白发生了什么。我显然释放了一切。 这是我在使用 --leak-check=full 运行 valgrind 时收到的两个泄漏错误:

41 (24 direct, 17 indirect) bytes in 1 blocks are definitely lost in loss record 5 of 6
43 (24 direct, 19 indirect) bytes in 1 blocks are definitely lost in loss record 6 of 6

这是项目结构:

typedef struct item Item;

struct item
{
    char *name;
    int reg;
    char *adress;
};

这里是 List 和 Node 结构:

typedef struct list List;
struct list
{
    Node* node;
    Node *First, *Last;
};

typedef struct node Node;]
struct node
{
    Item* item;
    Node* prox;
};

这里是初始化、插入和删除函数。我认为他们可能与错误有关:

List*
InitializeList()
{
    List* list = (List*)malloc(sizeof(List));

    list->First = list->Last = NULL;

    return list;
}

void
Insert(Item* student, List* list)
{
    Node* new = (Node*)malloc(sizeof(Node));
    new->prox = NULL;
    if (list->Last == NULL)
        list->First = list->Last = new;

    else
    {
        list->Last->prox = new;
        list->Last = list->Last->prox;
    }

    new->item = student;
}

Item*
Remove(List* list, int reg)
{
    Item* i = NULL;
    Node* ant = NULL;
    Node* seg = list->First;

    while (seg != NULL && seg->item->reg != reg)
    {
        ant = seg;
        seg = seg->prox;
    }

    if (seg == NULL)
    {
        i = NULL;
        return i;
    }

    if (seg == list->First && seg == list->Last)
    {
        i = seg->item;
        list->First = list->Last = NULL;
        free(seg);

        return i;
    }

    if (seg == list->Last)
    {
        i = seg->item;
        list->Last = ant;
        ant->prox = NULL;
        free(seg);

        return i;
    }

    if (seg == list->First)
    {
        i = seg->item;
        list->First = seg->prox;
        free(seg);
        return i;
    }

    else
    {
        i = seg->item;
        ant->prox = seg->prox;
        free(seg);
        return i;
    }

    free(seg);
}

这些是 main 函数的最后几行。第一次调用Remove函数的地方:

Item* ret = Remove(list, 123);
ret = Remove(list, 34);
list = Free_List(list);

【问题讨论】:

  • 它不会显示块分配的位置吗?
  • 确实如此,我在问题中写道。它在 InitializeItem 函数中。有这样一行:by 0x400B9C: InitializeItem。我只是向您展示了错误消息的一部分。
  • Item结构的定义可能提供线索
  • 这是一个 ADT。主要功能只是函数调用。另外,我没有写 main 函数。我的代码应该在不更改的情况下运行。
  • 您似乎修改了中间的列表,并且丢失了其中一个节点的踪迹。我们需要查看更多代码来提供帮助。

标签: c valgrind free


【解决方案1】:

在您的insert 方法的这一行中:

list->Last = list->Last->prox;

你忘记了之前列表中的内容->最后一个;你用新分配的指针替换它的值;所以之前在最后一个位置的项目永远不会被释放 --> 内存泄漏。

【讨论】:

    【解决方案2】:

    这是因为您没有从列表中释放已删除的项目(至少根据您在问题中提出的内容)。从列表中删除一项后,在主函数中释放整个列表,这当然会释放列表中的所有内容,但已从列表中删除的项目除外。

    为列表外的项目添加另一个类似的函数:

    void FreeItem(Item *it){
        free(it->name);
        free(it->adress);
        free(it);
    }
    

    我像下面这样测试了你的代码,没有内存泄漏:

    Item* ret = Remove(list, 123);
    ret = Remove(list, 34);
    list = Free_List(list);
    
    FreeItem(ret);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-08
      • 1970-01-01
      • 2011-01-27
      • 2016-11-03
      • 2014-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多