初始化嵌套结构

时间:2015-01-17 10:33:39

标签: c pointers struct

尝试初始化嵌套结构时遇到问题。

在编译时,没有错误,但在执行时,我得到了段错误。 在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;
};

直到我加入渔夫才行得很好。我不知道这是由于内存分配还是我初始化。

3 个答案:

答案 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;