【问题标题】:double free or corruption (fasttop) in my encoder我的编码器中的双重免费或损坏(fasttop)
【发布时间】:2014-06-25 04:15:59
【问题描述】:

我的程序涉及将树列表组合在一个队列中,我的程序完美编译并且适用于大约一半的代码,然后向我抛出此错误。我已经把它缩小到涉及我的freeTree以及我如何在encodefile中调用它,对于一些背景故事,这是一个基于文本文件中字符频率的编码器,所以如果有一个包含5个不同字符的文本文件,那么这段代码将从队列中的 5 个不同节点开始。队列中的每个初始节点都保存 char 和频率,优先级队列基于频率,以 tiebreaker 作为 char 的数值。

malloc_printerr (action=3, str=0x7ffff7b98938 "double free or corruption (fasttop)", ptr=0x6034b0) at malloc.c:5027

这是结构体的样子,符号代表字符,权重是频率

struct treeNode
{
  unsigned char symbol;
  unsigned long weight;
  struct treeNode* left;
  struct treeNode* right;
  struct treeNode* next;
};

struct queue
{
  struct treeNode* first;
  struct treeNode* last;
};

这是我的freeTree方法

void freeTree( struct treeNode* root )
{
  if( root != NULL )
  {
    freeTree( root->left );
    freeTree( root->right );
    free( root );
  }
}

这些是我在代码的主要部分中使用的变量或树节点

  struct treeNode* newNode;
  struct treeNode* holder;

这就是所有被调用的地方,应该通过我的队列将两个节点组合成一棵树,顶部的节点等于两个输入节点的权重,这应该一直持续到仅队列包含一棵大树

while( treeCount > 1 )
  {
    newNode = combineTwo( q->first, q->first->next );
    if( charCount == 2 )
    {
      holder = q->first;
      q->first = q->first->next;
      freeTree( holder );
      holder = q->first;
      q->first = newNode;
      freeTree( holder );
    }
    else
    {
      holder = q->first;
      q->first = q->first->next;
      freeTree( holder );
      holder = q->first;
      q->first = q->first->next;
      freeTree( holder );
      insertSortedNode( q, newNode );
    }
    charCount--;
    holder = NULL;
  }

这是我的 combineTwo 方法,它将两个输入节点变成一个节点上的叶子

struct treeNode* combineTwo( struct treeNode* first, struct treeNode* second )
{
  struct treeNode* newNode = createNode( '\0', (first -> weight) + (second -> weight));
  if( first -> weight > second -> weight )
  {
    newNode -> right = first;
    newNode -> left = second;
  }
  if( first -> weight < second -> weight )
  {
    newNode -> left = first;
    newNode -> right = second;
  }
  if( first -> weight == second -> weight )
  {
    if( first -> symbol > second -> symbol )
    {
      newNode -> right = first;
      newNode -> left = second;
    }
    if( first -> symbol < second -> symbol )
    {
      newNode -> left = first;
      newNode -> right = second;
    }
  }
  return newNode;
}

如果需要更多信息,我将整天在这里回答任何需要的问题

【问题讨论】:

  • treeNode.next 是指向什么的指针?它是子节点之一吗?
  • while( treeCount &gt; 1 ) 什么是树数? stackoverflow.com/q/23529555/905902
  • treeNode* -> next 与队列一起使用,当调用 next 时,它将进入队列中的下一个节点,并且您为我链接的页面不存在
  • treeCount 是队列中元素或树的数量,所以就像我给出的示例一样,如果输入文件有 5 个不同的字符,那么我的代码将使用 5 个不同的 treeNodes 创建一个队列
  • @Happilystoned:是的,它仍然存在。 (对于某些人)

标签: c tree free encoder


【解决方案1】:

combineTwo 创建一个新节点,该节点(可能)将newnodeleftright 指向firstsecond 参数值。然后,您的 while 循环中的代码使用 freeTree 释放这些指针。

例如:

newNode = combineTwo( q->first, q->first->next ); // newNode->left = q->first (possibly)
if( charCount == 2 )
{
  holder = q->first;
  q->first = q->first->next;
  freeTree( holder );      // freeing the original q->first here. newNode still points to it.

你需要确定新节点的左右是否应该指向原始树节点,或者是否应该删除它们(原始节点)。如果没有无效的指针,你就不能同时做这两件事。

【讨论】:

  • Ohhhhh,这很有意义,但我仍然有点不确定如何减少队列的大小,我可以先分配两个新节点 = q->first和 second = q->first->next 然后调用 combineTwo( first, second ) 会消除错误还是他们指向 q->first 可能仍然给出相同的错误? NM 那,你没有工作
  • 现在我明白了,但是就像上面所说的,现在我的问题是我如何能够在没有收到错误的情况下组合两个并仍然缩小队列,我会投票给你,但我没有 15 个代表
  • 您可以只从队列中删除项目而不释放它们,因为您已将指针移动到树中。 q-&gt;first = q-&gt;first-&gt;next; 会这样做。你最终会得到一棵大树和一个空队列。我不确定您的代码应该如何工作,因为当您将其放回队列时,您从未设置 newNode-&gt;next
  • 我建议先把它写在纸上,看看节点应该如何组合以及它们最终的位置。
  • 好吧,我试着实现它,而将 newNode 放回代码中的是 insertSortedNode,它会做所有需要放回队列中正确位置的事情,并且会做第二条评论
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多