克隆链表导致分段错误

Posted

技术标签:

【中文标题】克隆链表导致分段错误【英文标题】:Cloning the Linked List results in a segmentation Fault 【发布时间】:2017-12-24 03:56:21 【问题描述】:

我正在尝试将一个链表克隆到另一个链表,但出现分段错误。我有一个带有两个指针m_Nextm_Bak 的结构,并且我有一个存储名称的char 指针。我正在尝试用 C++ 来实现。我需要克隆src并返回一个克隆的链表。

TEMPLOYEE        * cloneList    ( TEMPLOYEE       * src ) 

    TEMPLOYEE* curr = src, *temp;

    while (curr) 
        temp = curr->m_Next;
        temp->m_Name = new char[strlen(curr->m_Name) + 1];
        strcpy ( temp->m_Name, curr->m_Name);
        curr->m_Next->m_Next = temp;
        curr = temp;
    

    curr = src;

    while (curr) 
        curr->m_Next->m_Bak = curr->m_Bak->m_Next;

        curr = curr->m_Next?curr->m_Next->m_Next:curr->m_Next;
    

    TEMPLOYEE* original = src, *copy = src->m_Next;

    temp = copy;

    while (original && copy)
    
        original->m_Next =
                original->m_Next? original->m_Next->m_Next : original->m_Next;

        copy->m_Next = copy->m_Next?copy->m_Next->m_Next:copy->m_Next;
        original = original->m_Next;
        copy = copy->m_Next;
    

    return temp;
  

编辑:

我知道问题出在哪里了。

TEMPLOYEE        * cloneList    ( TEMPLOYEE       * src ) 
    if(!src) return NULL;
    TEmployee * current = src;

    while(current)
        TEmployee * current_next = current->m_Next;
        current->m_Next  =  newEmployee(current->m_Name,current->m_Next);
        current->m_Next->m_Next = current_next;
        current = current_next;
    
    current = src;

    TEmployee * clone_head  = current->m_Next;

    while(current)
        TEmployee * clone = current->m_Next;
        if(current->m_Bak)
            clone->m_Bak    = current->m_Bak->m_Next;
        
        current = clone->m_Next;
    

    current = src;

    while(current)
        TEmployee * clone  = current->m_Next;
        current->m_Next = clone->m_Next;
        if(clone->m_Next)
            clone->m_Next = clone->m_Next->m_Next;
        
        current = current->m_Next;
    
    return clone_head;


【问题讨论】:

注意temp->m_Name = new char[strlen(curr->m_Name) + 1];这行表示你没有使用C;这是一个 C++ 结构。 我可以使用 C++ 但不能使用 stl 库。 一些调试思路: 1. 从应用程序中获取堆栈跟踪(可以在gdb 中运行直到它崩溃并运行bt 到see the stack) 2. 通过@ 运行代码987654322@ 查看可能发生无效访问的位置 3. Step through 使用 gdb 的函数检查您在什么时候看不到预期的行为。 确保在某个地方you don't violate the Rule of Three. 如果我没记错的话,正确实施三法则将完全消除对克隆功能的需要。 如果这里的目标是克隆一个链表,那么它在这里所做的事情从根本上是错误的。典型的链表克隆操作在单个while 循环中完成。我在这里看到了三个while 循环,每个循环的目的似乎都有些可疑,而且除了其他所有内容之外,它似乎很有可能像筛子一样泄漏内存。特别是作为第一个循环的结果。你需要退后一步,schedule an emergency appointment with your rubber duck 才能查明真相。 【参考方案1】:

对我来说突出的一个问题是,当您克隆列表时,您克隆的是数据,而不是用于存储数据的节点。这意味着您正在覆盖现有列表,并且您最终会得到一个将自身作为next 引用的节点(循环链接)。

因此,当您克隆列表时,除了复制数据之外,您还需要分配新的TEMPLOYEE 节点(到temp)。不要忘记记住您分配的第一个(新克隆列表的头部)以返回给调用者。

【讨论】:

以上是关于克隆链表导致分段错误的主要内容,如果未能解决你的问题,请参考以下文章

为啥释放内存会导致分段错误?

C即使分配了内存,修改链表的程序也会导致分段错误

C快速排序(链表)分段错误

链表中的分段错误

为啥我的字符串分配会导致分段错误?

确定导致分段错误的代码行?