将struct指针元素复制到指针似乎会破坏它

Fli*_*imm 5 c

我还在学习C,我必须在某些方面误解指针.

我的印象是,下面的线将通过复制存储在内存地址下l->firsttemp.它们都是struct list_el*指针,所以我看不出问题.

struct list_elt * temp;
temp = l->first;
Run Code Online (Sandbox Code Playgroud)

运行我的示例代码给了我一个无限循环:

user@machine:~$ gcc question.c 
user@machine:~$ ./a.out | head
append(): l->first->val: 30, l->first->next == NULL: 1
main()  : l->first->val: 30, l->first->next == NULL: 1
print() : l->first->val: 30, l->first->next == NULL: 1
print() : temp->val: 30, temp->next == NULL: 0
print() : temp->val: 30, temp->next == NULL: 0
print() : temp->val: 30, temp->next == NULL: 0
print() : temp->val: 30, temp->next == NULL: 0
print() : temp->val: 30, temp->next == NULL: 0
print() : temp->val: 30, temp->next == NULL: 0
print() : temp->val: 30, temp->next == NULL: 0
Run Code Online (Sandbox Code Playgroud)

这是question.c.对不起,我无法进一步缩小它,每次我做这个问题似乎神奇地消失了.

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

struct list_elt {
    int val;
    struct list_elt * next;
};
struct linked_list {
    struct list_elt* first;
};

void print(const struct linked_list * l);
struct linked_list* new_list(void);
void append(struct linked_list* l, int value);


main()
{
    struct linked_list * l;
    l = new_list();
    append(l, 30);
    printf("main()  : l->first->val: %d, l->first->next == NULL: %d\n", l->first->val, l->first->next == NULL);
    print(l);
}

struct linked_list* new_list()
{
    struct linked_list* l;
    l = (struct linked_list*) malloc(sizeof(struct linked_list));
    l->first = NULL;
    return l;
}

void append(struct linked_list* l, int value)
{
    struct list_elt el = {0, NULL};
    el.val = value;
    el.next = NULL;
    if (l->first == NULL) {
        l->first = (struct list_elt*) &el;
        printf("append(): l->first->val: %d, l->first->next == NULL: %d\n", l->first->val, l->first->next == NULL);
    } else {
        printf("append(): Unimplemented\n");
    }
}


void print(const struct linked_list * l)
{
    printf("print() : l->first->val: %d, l->first->next == NULL: %d\n", l->first->val, l->first->next == NULL);
    struct list_elt * temp;
    temp = l->first;
    while (temp != NULL) {
        printf("print() : temp->val: %d, temp->next == NULL: %d\n", temp->val, temp->next == NULL);
        temp = temp->next;
    }
    printf("\n");
}
Run Code Online (Sandbox Code Playgroud)

谢谢.

Has*_*kun 5

您正在append函数的堆栈上分配list_elt .函数返回后,此指针无效,不应再引用.

你应该分配你的元素malloc.


Nod*_*ode 1

你的append函数是错误的。它el在堆栈上分配,并使用列表中的指针。这样做的问题是,一旦在 后调用另一个函数append(在本例中为 ),内存就会被垃圾覆盖print。相反,使用 malloc 分配,例如:

int append(struct linked_list* l, int value)
{
    struct list_elt *el = malloc(sizeof(struct list_elt));

    if (el)
    {
        el->val = value;
        el->next = NULL;
        if (l->first == NULL) {
            l->first = el;
            printf("append(): l->first->val: %d, l->first->next == NULL: %d\n",
                   l->first->val, l->first->next == NULL);
        } else {
            printf("append(): Unimplemented\n");
        }

        return 0;
    }
    else
    {
        return 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Flimm,“el”必须是一个指针,因为结构的内存需要由“malloc”分配。如果像以前那样将其设置为值,则内存将在堆栈上本地分配,并且可能会被另一个函数调用覆盖。 (2认同)