【问题标题】:Segmentation fault on pointer to pointer assignment指针分配的指针分段错误
【发布时间】:2016-01-02 20:21:34
【问题描述】:

我正在实现霍夫曼压缩,并且我正在从包含节点的链接列表构建一个 hufftree。多次迭代后,我在指向分配指针的指针上出现分段错误。根据我的经验和研究,我认为分段错误是由于程序中断以外的错误引起的。任何帮助或建议将不胜感激。

P.S - 我是堆栈溢出的新手,以前从未问过问题,所以如果您需要更多信息来帮助我解决这个问题或其他任何问题,请告诉我。

struct LinkList{
    int weight;
    struct TreeNode * bottom;
    struct LinkList * next;
}; typedef struct LinkList LinkList;

//This function takes in a link list where each node points to the next
 //element in the link list and a huff tree node. It also contains weight 
//which is equal to the weight of the hufftree that it points to.

TreeNode * huffTree(LinkList * head)
{
    LinkList * temphead = head;
    LinkList * ptr;
    LinkList * ptr1;
    int count = 127,i;
    while(count>2)
    {
        temphead = head->next->next;
        head->next->next = NULL;
        head = mergeTree(head);
        ptr = temphead;
        ptr1 = temphead;// This is where I get the segmentation fault
//when the value of count is 14
        while(head->weight>temphead->weight)
        {
            ptr1 = temphead;
            temphead = temphead->next;
        }

        if(ptr1!=temphead)
        {
            head->next = temphead;
            ptr1->next = head;
            head = ptr;
        }

        else
        {
            head->next = temphead;
        }

        count--;
    }

    head = mergeTree(head);

    TreeNode * root;
    root = head->bottom;
    head->bottom = NULL;
    free(head);
    return root;
}

LinkList * mergeTree(LinkList * head)
{
    TreeNode * tree1 = head->bottom;
    TreeNode * tree2 = head->next->bottom;
    head->bottom = NULL;
    head->next->bottom = NULL;

    free(head->next);
    free(head);

    TreeNode * newnode = (TreeNode *) malloc(sizeof(TreeNode));

    newnode->weight = tree1->weight + tree2->weight;
    newnode->c = '~';
    newnode->left = tree1;
    newnode->right = tree2;

    LinkList * ptr = (LinkList *) malloc(sizeof(TreeNode));
    ptr->weight = newnode->weight;
    ptr->bottom = newnode;
    ptr->next = NULL;

    return ptr;
}

【问题讨论】:

  • 这是 C 还是 C++?它看起来像 C。
  • @PCLuddite - 是的,它是 c 代码
  • @jakshay_desai 那么你应该删除 C++ 标签。
  • @PCLuddite 对不起,我的错!删除它
  • temphead (head->next->next) 可以为空吗? while 循环是第一次访问,加载 temphead->weight 很容易看起来像调试器中的前一行,特别是在任何类型的优化中。

标签: c pointers tree malloc


【解决方案1】:

我的猜测是声明“while(head->weight>temphead->weight) {}”。 当您遍历列表时,您还没有检查头部是否变为 NULL。

【讨论】:

  • 我在遇到段错误之前打印出了列表,它不是空的,因此 head 也不是空的。为了避免您刚才描述的情况,我从 while(count>2) 开始。当 count = 14 时,程序给了我一个 seg 错误。所以一切正常,除了我在程序中犯了一些错误,直到 count 下降到 14 才影响代码。
【解决方案2】:

在您的“huffTree()”函数中,外部 while 循环 (while (count > 2)) 运行了 127 次迭代,因为 count 被初始化为 129。

因此,当调用者调用 huffTree() 时,输入列表 (LinkList *head) 必须有 129 个可用节点。

无论如何,如果列表中的节点少于 129 个,则应添加以下 NULL 条件处理。

temphead = head->next->next;
if (NULL == temphead)
{
    /* NULL condition handling */
}

当 temphead == NULL 时,则 temphead->权重取消引用将导致以下代码行中的分段错误

while(head->weight>temphead->weight)

head->如果保证 malloc() 在 mergeTree() 函数中不会失败,则权重很好。

【讨论】:

  • 没错!你的建议完全有道理,但是这个函数失败的测试用例发送了 129 个节点的列表(每个 ascii 字符占用一个节点)。我在分配 ptr1= temphead; 出现错误之前打印了列表和 temphead;两者都不是NULL。现在使用逻辑我知道如果 temphead!=NULL,ptr1=temphead 不是问题。问题存在于您建议的代码中的其他地方(可能在mergetree中),但我无法弄清楚这到底是什么或可能用于调试的技术
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-23
  • 2020-02-18
  • 1970-01-01
  • 1970-01-01
  • 2013-09-18
相关资源
最近更新 更多