C 链表中的内存

C 链表中的内存,c,C,我一直在用C编写一个简单的游戏来学习编程,但是当我使用链表时,我发现代码中有一个错误 这是我的结构: typedef struct ListShoots * ListShoots; struct ListShoots{ Shoot d; ListShoots next; }; 我的记忆功能: ListShoots Shoots_Create(int x, int y){ ListShoots ld = mallo

我一直在用C编写一个简单的游戏来学习编程,但是当我使用链表时,我发现代码中有一个错误

这是我的
结构

    typedef struct ListShoots * ListShoots;

    struct ListShoots{
        Shoot d;
        ListShoots next;
    };
我的记忆功能:

    ListShoots Shoots_Create(int x, int y){
        ListShoots ld = malloc(sizeof(struct ListShoots));
        ld->d.alto = 10;
        ld->d.x = x;
        ld->d.y = y;
        ld->d.v = 6;
        ld->next = NULL;
        return ld;
    }

    void Shoots_Shoot(ListShoots ld, int x, int y){
        ListShoots aux = ld;
        if(ld==NULL) printf("ld = NULL\n");
        while(ld!=NULL) ld = ld->next;
        ld = Shoots_Create(x,y);
        ld = aux;
        if(ld==NULL) printf("ld = NULL (again)\n");
    }
当我在main中调用函数
Shoots\u Shoot
时(首先,
ld=NULL
),我得到的输出是:
ld=NULL
ld=NULL(再次)
。为什么?我认为应该只有第一行
printf
,因为在第一行
while(ld!=NULL)ld=ld->next
什么都不做

奇怪的是:如果我删除行
ld=aux
,输出正常,只是:
ld=NULL

编辑:问题是:
aux
ld
指向同一内存,因为
aux=ld
。因此,如果我为
ld
保留内存,那么
aux
会立即更改,并且不会指向
NULL
,对吗

。。。我也得到了输出:“ld=NULL”和“ld=NULL(再次)”。为什么

因为

ListShoots aux = ld;
/* ... */
ld = aux;
您正在恢复
ld
的原始值,该值显然是
NULL
,因为您得到了

ld = NULL


关于您描述的具体问题,请查看您的函数

void Shoots_Shoot(ListShoots ld, int x, int y){
    ListShoots aux = ld;
    if(ld==NULL) printf("ld = NULL\n");
    while(ld!=NULL) ld = ld->next;
    ld = Shoots_Create(x,y);
    ld = aux;
    if(ld==NULL) printf("ld = NULL (again)\n");
}
第一行将传入的
ld
值存储在
aux
变量中。如果
ld
为空,则打印

稍后更改
ld

ld = Shoots_Create(x,y);
但紧接着(在printf之前)再次使用下一行返回其原始值

ld = aux;
因此,本质上两个条件都在测试相同的值(传递给函数的
ld
的值)。这就是为什么当您删除该行时

ld = aux;

它可以工作-因为这样您就不会更改创建(x,y)函数的返回值

-auxld在这里指向相同的内存:

 ListShoots aux = ld;
-但现在,如果此循环至少完成一次,则它们不指向相同的内存:

while(ld!=NULL) ld = ld->next;
-现在ld由于malloc指向另一个空间内存,而aux仍然指向相同的位置:

 ld = Shoots_Create(x,y);
-您还记得您说过aux在开始时指向NULL吗?好的,现在ld再次指向与aux相同的内存。它表示空:

ld = aux;

Aux始终是相同的值(方法启动时ld的值),因此两个条件测试始终打印相同的值。

您从未设置列表最后一个元素的
。下一个
指向您创建的新元素。可能
listshots*ld
是。但是
aux
ld
指向同一内存,因为
aux=ld
。因此,如果我为
ld
保留内存,则会立即
aux
更改,并且不会指向NULL,不是吗?但在初始化
aux
后,您永远不会更改它!!您只需多次更改
ld
。最后将其设置回
aux
,但是
aux
始终是相同的值,因此两个条件测试相同的值。您的
printf
语句将始终打印零次或两次,而不是一次。使用调试器逐步检查代码,您将看到发生了什么。但是
aux
ld
指向同一内存,因为
aux=ld
。所以,如果我为ld保留内存,它会立即改变,并且不会指向NULL,不是吗?不,不是这样的。当您为
ld
保留内存时,
aux
完全不受此影响。要获得您想要的行为,您需要另一层间接。使用
ListShoots*aux=&ld
ld=*aux
ld = aux;