尝试初始化嵌套结构时遇到问题。
在编译时,没有错误,但在执行时,我得到了段错误。 在valgrind,我得到
> Invalid read of size 8 at 0x402175: new_animal
> Address 0x38 is not stack'd, malloc'd or (recently) free'd
以下是代码:
void new_animal(int i, int j, int species){
struct animal * a;
if (array[i][j]==NULL)
{
a = malloc(sizeof(struct animal));
assert (a);
a->espece=espece;
if(array[i][j]->player==NULL)
{
a->player->id_fisherman=0;
strcpy(a->player->Name,"N"); //I want it set to NULL.
}
}
grille[i][j] = a;
}
以下是两种结构:
struct fisherman {
int id_fisherman;
char Name[10];
};
struct animal {
int species;
struct fisherman* player;
};
直到我加入渔夫才行得很好。我不知道这是由于内存分配还是我初始化。
答案 0 :(得分:4)
a->player = malloc(sizeof(struct fisherman));
在向内容写入内容之前,您需要将内存分配给struct Fisherman
答案 1 :(得分:3)
其中一个问题是:
if (array[i][j]==NULL) {
// ... then ...
if(array[i][j]->player==NULL)
}
如果array[i][j]
为NULL
,则您无法取消引用它。您必须先将其分配给有效的指针。
答案 2 :(得分:0)
让我们按照代码将解释分成几部分。
执行a = malloc(sizeof(struct animal));
时, 种 属性上的 0 结构,以及内存垃圾 播放器 属性,因为它是未初始化的指针。
正如@Gopi所说,你必须在使用之前初始化这个指针:
a->player = malloc(sizeof(struct fisherman));
现在,以下声明有效:
a->player->id_fisherman=0;
在使用指针之前,a->player
更好地断言它。 C编译器在可能的运行时错误检测方面不是很可靠。在生产代码中,您可以将编译器设置为不要断言。
避免此类错误的提示是创建初始化函数以及结构的定义。 你可以写:
struct fisherman {
int id_fisherman;
char Name[10];
};
*fisherman malloc_fisherman(){
return malloc(sizeof(struct fisherman));
}
*fisherman malloc_fisherman(int id){
struct fisherman *a = malloc(sizeof(struct fisherman));
a->id_fisherman = id;
return a;
}
在这里,您将创建两个函数,一个用于默认创建,另一个用于创建具有给定参数的结构。结构 动物 可以依靠这些函数来创建自己的创建函数。
Philip Guo撰写了一篇关于基本C编程良好实践的精彩文章。 Check it out,特别是 部分使用断言语句来记录和执行函数前置条件和其他假设 。
OBS:以下陈述是不是错了?不是名为 species 的属性,而不是 espece ? a->espece=espece;