在C中设计游戏实体系统时,我尝试了一种"平等"初始化方法。我很惊讶地看到林格告诉我,在我的init函数末尾有内存泄漏,并且我的变量ent
从未在以下代码中初始化。事实证明是正确的,因为我有一个"巴士错误":
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int x;
int y;
} entity_t;
void entity_init(entity_t* ent, int _x, int _y)
{
ent = malloc(sizeof(*ent));
ent->x = _x;
ent->y = _y;
}
int main(void)
{
entity_t* ent;
entity_init(ent, 10, 24);
printf("Entity: x%d y%d", ent->x, ent->y);
return 0;
}
i 思想上面的代码会做的是以我的空ent
指针作为参数,告诉它指向一些新分配的内存,然后填充该内存,一切都将是美好的。我不知道造成"公共汽车错误"的真正在做什么,我是否错过了对指针和malloc的批评?
i 隐约记住在某些C代码中看到与此之前非常相似的事情(等于无结构初始化),我强烈希望使用与此类似的平等无初始化样式(Broken))代码如果在c。
移动malloc
在初始化函数之外呼叫:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int x;
int y;
} entity_t;
void entity_init(entity_t* ent, int _x, int _y)
{
ent->x = _x;
ent->y = _y;
}
int main(void)
{
entity_t* ent;
if(NULL==(ent = malloc(sizeof(*ent))))
return 1;
entity_init(ent, 10, 24);
printf("Entity: x%d y%d", ent->x, ent->y);
return 0;
}
您将指针分配给分配的块到本地变量(ENT)。这不会影响main
中的ent
。
如果要将malloc
保存在entity_init
中,则应使用双指针,但还应更改签名以允许从entity_init
malloc
失败的方法 int entity_init(entity_t **ent, int _x, int _y)
{
if(NULL==(*ent = malloc(sizeof(**ent))))
return -1;
(*ent)->x = _x;
(*ent)->y = _y;
}
int main(void)
{
entity_t* ent;
if(0>entity_init(&ent, 10, 24))
return 1;
printf("Entity: x%d y%d", ent->x, ent->y);
return 0;
}
更常见的模式是:
entity_t *entity_new(int _x, int _y)
{
entity_t *ent = malloc(sizeof(*ent));
if (NULL==ent)
return NULL;
ent->x = _x;
ent->y = _y;
return ent;
}
int main(void)
{
entity_t* ent;
if(NULL==(ent=entity_new(10,24)))
return 1;
printf("Entity: x%d y%d", ent->x, ent->y);
return 0;
}
如果必须在entity_init()
函数中分配,则需要将指针返回到分配,或者通过将ent
作为指向entity_t
的指针来添加间接层。在已发布的代码中,entity_init()
ent
中的指示器是传递给该功能的指针的A copy 。对该指针进行的任何更改,例如将内存分配的地址分配给指针,从调用函数中看不到,因为该副本将在函数返回后停止存在。
另外,请注意,您需要检查从malloc()
返回的值,以确保分配成功。如果成功,该功能可以继续进行初始化过程。如果不是,则ent
可以保留为null指针,该指针应在调用功能中检查:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int x;
int y;
} entity_t;
void entity_init(entity_t **ent, int _x, int _y)
{
*ent = malloc(sizeof **ent);
if (*ent) {
(*ent)->x = _x;
(*ent)->y = _y;
}
}
int main(void)
{
entity_t *ent;
entity_init(&ent, 10, 24);
if (ent == NULL) {
fprintf(stderr, "Allocation failure in entity_init()n");
exit(EXIT_FAILURE);
}
printf("Entity: x%d y%dn", ent->x, ent->y);
return 0;
}
程序输出:
Entity: x10 y24