1

我在将单个链接列表复制到双链接列表时遇到了一些麻烦。不知道发生了什么,但我遇到了 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;
}
4

3 回答 3

3

在您的函数中,您只为双向链表中的第一个doublify分配足够的空间。当您使用 遍历单链表时,您需要在每次循环迭代时为新的分配空间,为单链表中的每个元素分配一个空间。 dnodecurrdnode

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

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

于 2012-07-28T06:24:17.307 回答
1

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

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

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;
}
于 2012-07-28T06:40:06.280 回答
0

Maksim 有一个很好的答案,对我有帮助,但如果你有...

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
        }
    }
}

我在课堂上遇到了同样的问题,所以也许这会为将来的人节省一些精力!

于 2014-03-16T16:05:41.220 回答