C 链表中的内存
我一直在用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
结构
:
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)函数的返回值-aux和ld在这里指向相同的内存:
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;