查看链表的项目

时间:2014-08-18 19:29:15

标签: c list linked-list

我想查看链表的所有项目。

我创建了一个三项列表,当我使用下面的" show_items"函数,它只显示第一个元素,而其他项目不能显示,因为编译器会给出分段错误错误。

#include <stdio.h>
#include <stdlib.h>

struct list{
    int age;
    struct list *next;
};

void create_item(int *total_items, struct list *where_is_first_item, struct list *where_is_last_item)
{
struct list *generic_item;
generic_item = malloc(sizeof(struct list));
printf("\nage of item %d: ", (*total_items)+1);
scanf("%d", &generic_item->age);

if(*total_items == 0){

    where_is_first_item->next=generic_item;
    where_is_last_item->next=generic_item;
    printf("\nitem created\n");
}
else{

    where_is_last_item->next=generic_item;
    printf("\nitem created\n");
}

void show_items(int *total_items, struct list *where_is_first_item, struct list *temp){
    temp=where_is_first_item->next;
    int i;
    for(i=0;i<*total_items;i++){
        printf("age of element %d: %d\n", i+1, temp->age);
        temp=temp->next;
    }
}

int main (void){
    int total_items=0;
    struct list *where_is_first_item;
    where_is_first_item=malloc(sizeof(struct list));        
    struct list *temp;
    temp=malloc(sizeof(struct list));
    printf("\n\n\tCREATE A NEW ITEM\n");
    create_item(&total_items, where_is_first_item, where_is_last_item);
    total_items++;
    show_items(&total_items, where_is_first_item, temp);
    return 0;
}

2 个答案:

答案 0 :(得分:1)

好吧,我在代码中看到了两个主要问题:

  1. 我没有看到在问题陈述中声明的三个成员。
  2. malloc()返回的内存包含未指定的内容,并且您希望它具有有用的内容。
  3. 然后是奇怪的事情:

    1. 如果你从不修改它,为什么要将total_items作为指针传递。
    2. 如果您立即忽略传入的值,为什么要将temp作为参数传递?

答案 1 :(得分:0)

在遍历列表时,您应该检查temp的值,以确保它在尝试访问之前不是NULL。至少,您应该使用以下内容:

for ( i = 0; i < *total_items && temp != NULL; i++ )
 ...

虽然迭代像

这样的列表更常见
while ( temp != NULL ) // or just while ( temp )
{
  ...
  temp = temp->next;
}

您对temp的使用似乎很困惑;在您致电main后,show_items中是否有任何用途?如果没有,你应该将它作为show_items的本地,而不是作为参数传递:

void show_items(int *total_items, struct list *where_is_first_item)
{
  struct list *temp = where_is_first_item->next;
  ...
}

在您发布的代码中,total_items被初始化为0;如上所述,此代码不应尝试输出任何内容。如果您要发布您遇到问题的实际代码,或者如果它太大,请将其缩小为问题的代表性样本,这将使每个人的生活更轻松。

修改

咄。现在我看到了问题。您永远不会在next结构中正确设置generic_item项目。

因此,您有两个指针可以跟踪列表的头部和尾部,where_is_first_itemwhere_is_last_item。当您将第一个项目添加到列表中时,您创建generic_item并设置您的头尾指针,通过各自的next成员指向它,为您提供类似的内容(使用headtail代替where_is_first_itemwhere_is_last_item以简洁起见:

head           generic_item   tail
+--+--+        +--+--+        +--+--+
|  | -+------->|  | -+-???    |  | -+---+
+--+--+        +--+--+        +--+--+   |
               ^                        |
               |                        |
               +------------------------+

到目前为止一切顺利。但是,当您添加第二个项目时,您只更新列表尾部指针;你不会创建从第一个项目到第二个项目的显式链接,所以你最终得到如下内容:

head                          generic_item    tail
+--+--+        +--+--+        +--+--+         +--+--+
|  | -+------->|  | -+-???    |  | -+-???     |  | -+--+
+--+--+        +--+--+        +--+--+         +--+--+  |
                              ^                        |                         
                              |                        |
                              +------------------------+

希望你能看到问题所在。永远不会初始化第一个列表元素中的next指针,因此它包含一个与有效地址不对应的不确定值。

将新元素附加到列表时需要额外的步骤:

struct list *pre = where_is_last_item->next;
pre->next = generic_item;
where_is_last_item->next = generic_item;

这将为您提供以下内容:

head           pre            generic_item    tail
+--+--+        +--+--+        +--+--+         +--+--+
|  | -+------->|  | -+------->|  | -+-???     |  | -+--+
+--+--+        +--+--+        +--+--+         +--+--+  |
                              ^                        |                         
                              |                        |
                              +------------------------+

通常,您应该始终将next成员初始化为NULL,而不是让它不确定。对NULL进行测试很容易;确定非NULL指针值的有效性要困难得多。