2013-10-21 107 views
-2

我必须使用链接列表(因此指针)在c中打印一个集合的列表。但是,当我删除列表的第一个元素并尝试打印列表时,它只是显示了很多地址。有什么问题可能是什么建议?谢谢!删除链接列表的第一个节点

删除功能:

int delete(set_element* src, int elem){ 
if (src==NULL) { 
    fputs("The list is empty.\n", stderr); 
} 


set_element* currElement; 
set_element* prevElement=NULL; 

for (currElement=src; currElement!=NULL; prevElement=currElement, currElement=currElement->next)  { 
    if(currElement->value==elem) { 
     if(prevElement==NULL){ 
      printf("Head is deleted\n"); 
      if(currElement->next!=NULL){ 
       *src = *currElement->next; 
      } else { 

       destroy(currElement); 
      } 
     } else { 
      prevElement->next = currElement->next; 
     } 
     // free(currElement); 
     break; 
    } 
    } 



return 1; 
} 



void print(set_element* start) 
{ 
    set_element *pt = start; 

    while(pt != NULL) 
    { 
     printf("%d, ",pt->value); 
    pt = pt->next; 
    } 
} 
+2

很难说没有任何代码,但问题可能是您正在尝试释放其头部进入后打印的清单。更新指向列表的指针,指向'head-> next'条目,并且您应该是golden。 –

+0

你是如何打印清单的? –

+0

您可能想阅读[Stack Overflow问题清单](http://meta.stackexchange.com/questions/156810/stack-overflow-question-checklist),它会帮助您编写更好的问题。 –

回答

0

如果列表指针与指向第一个元素的指针相同,那么当第一个元素为free时,列表指针不再有效。

有两个解决这个问题:

  1. 让你的所有列表方法采取的指针列表,使他们能够neccesary时更新。这种方法的问题是如果你在另一个变量中有一个指针副本,那么这个指针也会失效。

  2. 不要让你的列表指针指向第一个元素。让它指向一个指向第一个元素的指针。

示例代码:”

typedef struct node_struct { 
    node_struct *next; 
    void *data; 
} Node; 


typedef struct { 
    Node *first; 
} List; 
0

警告:这个答案包含推断代码。

C中的一个典型的链表看起来有点像这样:

typedef struct _list List; 
typedef struct _list_node ListNode; 

struct _list { 
    ListNode *head; 
} 

struct _list_node { 
    void *payload; 
    ListNode *next; 
} 

为了正确地从列表中删除第一个元素,下面的序列需要发生:

List *aList; // contains a list 

if (aList->head) 
    ListNode *newHead = aList->head->next; 

delete_payload(aList->head->payload); // Depending on what the payload actually is 
free(aList->head); 
aList->head = newHead; 

这里的操作顺序非常重要!试图在没有先释放旧值的情况下移动头部会导致内存泄漏;在没有首先获得新头的正确价值的情况下释放旧头会产生未定义的行为。

附录:偶尔,上述代码的_list部分将被完全省略,从而将列表和列表节点保留为相同的东西;但是从你描述的症状来看,我猜这可能不是这种情况。

但是,在这种情况下,步骤基本上保持不变,但没有aList->位。


编辑:

现在,我看到你的代码,我可以给你一个更完整的答案。

你的代码中的一个关键问题是它到处都是。然而,有,在这里一条线这是特别糟糕:

*src = *currElement->next; 

这不工作,是什么原因造成你的崩溃。

就你而言,解决方案是以某种容器的方式封装链表,如上面的struct _list结构;或者修改你现有的代码来接受一个指向set元素的指针,这样你就可以传递指针来设置元素(这就是你想要做的)。

就性能而言,这两种解决方案可能尽可能接近,因此毫无差别,但使用包装列表结构有助于交流意图。它还有助于防止其他指向列表的指针由于头部删除而变成乱码,所以就是这样。

+0

我不明白你的意思。我改变了方法,但它仍然是一样的。 代码: void destroy(set_element * head) { set_element * current = head; set_element * temp; (当前!= NULL) temp = current; current = current-> next; free(temp); } } – user90790

0

这通常发生在您删除不属于您的指针(实际上是一块内存)时。仔细检查你的函数,确保你没有释放你已经释放的指针,或者释放一个你没有用“malloc”创建的指针。