【问题标题】:"A heap has been corrupted" after using malloc twice使用 malloc 两次后“堆已损坏”
【发布时间】:2019-01-22 03:40:32
【问题描述】:

我有一个我正在尝试构建的“单词”链表,我创建了一个名为“add_to_mem”的函数,它将下一个单词添加到链表中。 我对代码进行了几次检查,发现他工作了两次——一次是当链表为 NULL 时,一次不是——它确实有效,但第三次我打电话到该方法 - 我收到一个“堆已损坏”错误。 代码:

    typedef struct { unsigned int val : 14; } word;

    typedef struct machine_m

    {

    word * current;
    int line_in_memo;
    char * sign_name;

    struct machine_m * next_line;
}Machine_Memo;

功能:

    /*Adding a word to the memory.*/
void add_to_mem(word * wrd, int line, char * sign_name)
{
    Machine_Memo * temp = NULL, *next = NULL;
    if (machine_code == NULL)
    {

        machine_code = (Machine_Memo *)malloc(sizeof(Machine_Memo));
        if (machine_code == NULL)
        {
            printf("Memory allocation has failed.");
            exit(1);
        }
        machine_code->current = wrd;
        machine_code->line_in_memo = line;
        machine_code->sign_name = sign_name;
        machine_code->next_line = NULL;

    }
    else
    {
        printf("token has been reached");
        temp = machine_code;
        next = (Machine_Memo *)malloc(sizeof(Machine_Memo)); //Line of error
        if (next == NULL)
        {
            printf("MEMORY ALLOCATION HAS FAILED. EXITING PROGRAM.\nThe problem has occured on code line %d", 775);
            exit(0);
        }
        next->current = wrd;
        next->line_in_memo = line;
        next->sign_name = sign_name;
        next->next_line = NULL;

        while (temp->next_line != NULL)
        {
            temp = temp->next_line;
            temp->next_line = next;

        }


    }
}

【问题讨论】:

  • 避免使用全局变量(即machine_code
  • 可以,但只是为了从中学习——为什么不使用全局变量?
  • 显然,全局变量不好,因为私有封装好。研究私有封装
  • 问题未重现。但无论如何,函数中的每个malloc 都会泄漏大量内存。您不必将指向 word 的指针保留在您的机器中。

标签: c visual-studio malloc heap-memory


【解决方案1】:

据我了解代码,它不会创建链接列表。它会创建节点,但不会将它们链接在一起。

在第一次调用时,machine_code(列表头)被创建。 在下一次调用时,会创建节点“下一个”,但是,循环:

while (temp->next_line != NULL)
    {
        temp = temp->next_line;
        temp->next_line = next;
    }

什么都不做,因为 'machine_code->next' 的值为空。所以循环内的代码不会被执行。我们在这里没有得到 linked 列表,而是零星的节点没有相互连接。 您可能希望(如在此处的另一篇文章中指出的那样)具有以下内容:

while (temp->next_line != NULL)
    {
        temp = temp->next_line;
    }
temp->next_line = next;

【讨论】:

  • 我不小心将temp->next_line = next 放在了循环中,现在当它再次出现时它仍然无法正常工作,我收到了同样的问题。
  • 能否添加调用代码,这样我们得到一个完整的程序,我们可以查看。
  • 整个程序900多行,如果你喜欢我可以上传到github,但我认为它与函数的行为无关
  • 我认为堆损坏的问题不在于您在此处发布的代码,而在于您程序的其他代码。我建议您尝试通过编写尽可能小的导致您遇到的问题的程序来隔离问题。顺便说一句,有用于堆损坏检测的工具。见stackoverflow.com/questions/2470131/…
  • 好吧,当我越来越想的时候,问题可能是由一个永恒的来源引起的,比如它的输入,是将一个 14 位结构复制到一个 word 类型是个好主意,这可能是导致它的原因吗?我现在就试着调试一下
【解决方案2】:

这里

        while (temp->next_line != NULL)
        {
            temp = temp->next_line;
            temp->next_line = next; // move out of the loop
        }

您可能希望将最后一个分配移到循环之外。

【讨论】:

    猜你喜欢
    • 2020-01-15
    • 2021-09-23
    • 2012-07-24
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多