为什么在链表中添加新值会覆盖现有内容?

时间:2018-02-11 22:20:52

标签: c linked-list

我正在尝试使用for循环将随机生成的值添加到链接列表中。当我尝试打印列表时,它具有正确的条目数,但它们都匹配输入的最后一个项的值。

这是代码。

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

typedef struct student {
    int num;
    char* name;
} student;

typedef struct container {
    student* data;
    struct container* next;
} container ;

container* front;
container* back;

container* createContainer(student* data) {

    container* tmp = malloc(sizeof(container));

    tmp->data = data;
    tmp->next = NULL;

    return tmp;

}

int add(student* to_add) {

    printf("%d %s\n", to_add->num, to_add->name);

    back->next = createContainer(to_add);
    back = back->next;


    return 1;
}

void printList(container* front) {

    container* tmp = front;

    int i;
    i=0;
    while (tmp != NULL) {
        i++;
        printf("%d:\t%d\t\t%s\n", i, tmp->data->num, tmp->data->name);
        tmp = tmp->next;
    }

}

int main(void) {
    srand(time(NULL));

    student st = {rand(), "test"};
    front = createContainer(&st);
    back = front;

    printList(front);

    int i;
    for (i=0; i<12; i++) {
        st.num = rand();
        st.name = "test";
        add(&st);
    }

    printList(front);

    // print the third value stored in the list.
    container* tmp = front->next->next;
    printf("%d\t\t%s\n", tmp->data->num, tmp->data->name);

    return EXIT_SUCCESS;
}

以下是它的输出:

1:  25312       test
17285 test
3447 test
8299 test
14310 test
22628 test
31306 test
8682 test
31936 test
18951 test
4107 test
7910 test
20556 test
1:  20556       test
2:  20556       test
3:  20556       test
4:  20556       test
5:  20556       test
6:  20556       test
7:  20556       test
8:  20556       test
9:  20556       test
10: 20556       test
11: 20556       test
12: 20556       test
13: 20556       test
20556       test

第一行显示正确添加了第一个值。非编号行是列表中的值,编号行显示实际存储在列表中的值。最后一行只是打印存储在列表中的第三个值,只是为了表明它(希望)不是打印功能的问题。

1 个答案:

答案 0 :(得分:4)

在您的所有程序中,只有一个student对象:

student st = {rand(), "test"};

main)。

其余代码会创建一个链接列表,其中包含指向此对象的十几个指针。当您检查列表时,您按照指针并打印相同的对象12次。

(另外,它不是添加到您的链接列表中覆盖内容的行为,它是main中的这些行:

    st.num = rand();
    st.name = "test";

在此处修改程序中单独student的内容。)

为了解决这个问题,您需要创建多个student个对象,每个列表元素一个。最简单的方法是让container直接存储student

typedef struct container {
    student data;  // not a pointer
    struct container *next;
} container;

然后调整所有函数以使用此数据结构。