【问题标题】:Initializing nested structures初始化嵌套结构
【发布时间】:2015-01-17 10:33:39
【问题描述】:

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

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

在我添加渔夫之前,它运行良好。不知道是内存分配的原因,还是我在初始化的时候。

【问题讨论】:

  • 这与“嵌套”结构无关。
  • 两者之一:或者您将player 字段声明为仅struct fisherman(没有*),或者您对其执行另一个malloc(),或者将指针初始化为有效(某物的地址)。

标签: c pointers struct


【解决方案1】:
a->player = malloc(sizeof(struct fisherman));

你需要先给struct Fisherman分配内存

【讨论】:

    【解决方案2】:

    这里有一个问题:

    if (array[i][j]==NULL) {
        // ... then ...
        if(array[i][j]->player==NULL)
    }
    

    如果array[i][j]NULL,那么您不能取消引用它。您必须首先将其分配给一个有效的指针。

    【讨论】:

      【解决方案3】:

      让我们按照代码将解释分成几部分。

      当您执行a = malloc(sizeof(struct animal)); 时,您会在 species 属性上拥有一个带有 0 的结构,以及 内存垃圾 strong> 在 player 属性上,因为它是一个未初始化的指针。

      正如@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;
      }
      

      在这里,您将创建两个函数,一个用于默认创建,另一个用于创建具有给定参数的结构。 struct animal 可以依赖这些函数来制作自己的创建函数。

      Philip Guo 撰写了一篇关于基本 C 编程良好实践的精彩文章。 Check it out,特别是使用断言语句记录和执行函数前置条件和其他假设部分

      OBS:下面的说法是不是错了?属性不是名为 species 而不是 espece

      a->espece=espece;

      【讨论】:

      • 你说得对,它们被称为物种,而不是物种。翻译的时候忘记改了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多