C编程,双向链表复制问题

时间:2012-07-28 06:07:51

标签: c linked-list

我在将单个链接列表复制到双链接列表时遇到了一些麻烦。不知道发生了什么,但我有一个gdb调试错误:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000
0x0000000100000d86 in doublify (list=0x1001008c0) at lists.c:62
62     newDlist->item = curr->item;

单向链接列表正在运行,

我的.h标题文件:

typedef struct _node {
   Item item;
   link next;
} node;

typedef struct _dnode *dlink;

typedef struct _dnode {
   Item item;
   dlink prev;
   dlink next;
} dnode;

我的代码:

link newLink (Item item){
   link createLink = malloc(sizeof(node));
   createLink->item = item;

   return createLink;
}

link fromTo (int start, int end) {
   link newList = NULL;

   if(start <= end ){
       newList = newLink(start);
       newList->next = fromTo(start+1, end);
   }

   return newList;
}

//Heres where it isn't able to copy the linklist item over into the new dlist.
dlink doublify (link list) {
   dlink newDlist = malloc (sizeof (dnode));
   link curr = list;

   while(curr != NULL){
       newDlist->item = curr->item;
       curr = curr->next;
       newDlist = newDlist->next;
   }
   return newDlist;
}

3 个答案:

答案 0 :(得分:3)

doublify函数中,您只为双向链接列表中的 first dnode分配足够的空间。当您使用curr沿着单链表行进时,您需要在每个循环迭代中为新dnode分配空间,单独为每个元素分配一个空间链接列表。

您收到错误,因为在第二次迭代中您尝试访问newDlist->next,这是一个未初始化的内存地址。

请注意,在创建双向链接列表时,您还需要保留指向上一个dnode的tmp指针,以便正确设置prev / next指针。 / p>

答案 1 :(得分:1)

问题发生在while循环的第二次迭代中。将newDlist分配给“下一个”项时,“下一个”字段可能包含任何值。问题是malloc只是给你一个指向任何值的数据区域的指针(它不会以某种方式清除它或init)。

您只需在每次迭代时分配一个新节点并相应地设置指针。这是如何做到这一点的方法之一。

dlink prevNode = NULL;

// Insert the first item (if present) to simplify the loop
if ( curr != NULL )
{
   dlink newDlist = malloc(sizeof(dnode));

   newDlist->item = curr->item;
   newDlist->next = NULL;
   newDlist->prev = NULL;
   prevNode = newDlist;

   curr = curr->next;
}

while ( curr != NULL )
{
   dlink newDlist = malloc(sizeof(dnode));

   newDlist->item = curr->item;

   prevNode->next = newDlist;
   newDlist->prev = prevNode;
   newDlist->next = NULL;

   prevNode = newDlist;
   curr = curr->next;
}

答案 2 :(得分:0)

马克西姆有一个很好的答案帮助了我,但如果你有......那就简化答案。

void DisplayList(topNode* nodeType) {
    node* ptrNode = nodeType;

    while (ptrNode->next != NULL) {
        // DO WORK
    }
}

...然后你需要把它改成......

void DisplayList(topNode* nodeType) {
    node* ptrNode = new node;           // THIS IS THE KEY...ALLOCATE THE MEMORY

    if (ptrNode == NULL)
        cout << "Could not allocate memory -- exiting application!" << endl;
    else {
        ptrNode = nodeType;             // THEN COPY THE TOP NODE POINTER

        while (ptrNode->next != NULL) {
            // DO WORK
        }
    }
}

我在课堂上遇到了同样的问题,所以也许这将为将来的某些人付出一些努力!