Malloc() C 中的双重嵌套结构

Malloc() a double nested struct in C

目标是让类型为 unit 的结构在 struct line 中填充该数组,而 struct line 在 struct fullData 中填充数组,因此它基本上变成一个二维数组,如下所示:

|------|-----|-----|
|   a  |  b  |  c  |
|------|-----|-----|
|   b  |     |     | 
|------|-----|-----|
|   a  |  b  |     |
|------|-----|-----|

each square is a unit
each row is a line
i guess fullData is just the square around the outside that accomplishes nothing

在我的代码中,我双重嵌套了一个结构,但不知道如何 malloc 一个结构,里面有一个结构数组,里面有一个结构数组:

/*Unit struct is where the unit tokens go directly to, they see if the
 struct is a not, and also hold the variable of the struct */
typedef struct unit
{
    bool isNot;
    char letter;
} unit;

/* The Line Struct has an array of structs, the unit struct will go in here */
typedef struct line
{
    struct* clause;
} line;

/*fullData struct has an array of stucts too, the line structs will go in here */
typedef struct fullData
{
     struct* table;
} fullData;

这是我现在分配它们的方式,但它似乎是错误的:

struct fullData Block;
struct Line lines;
Block.table = malloc(max_number_of_lines * sizeof(struct lines));
lines.clause = malloc(number_of_unit * sizeof (struct unit));

首先,它不是嵌套结构,它是指向结构的指针。

typedef struct unit
{
    bool isNot;
    char letter;
} unit;

/* The Line Struct has an array of structs, the unit struct will go in here */
typedef struct line
{
    struct* clause;
} line;

typedef struct fullData
{
     struct* table;
} fullData;

您使用 typedef for unit end line 但您没有使用它们在其他结构中声明参数。您应该将 struct * 更改为 lineunit。 不要使用同名unitlinefullData之类的,应该使用不同的名字,例如:

typedef struct __unit
{
    bool isNot;
    char letter;
} unit;

/* The Line Struct has an array of structs, the unit struct will go in here */
typedef struct __line
{
    unit* clause;
} line;

typedef struct __fullData
{
     line* table;
} fullData;

struct fullData Block;
struct Line lines; // even "Line" here is not exact 

应更改为:

fullData Block;
line lines;

为什么你认为你的 malloc 失败了?这取决于您如何在代码中使用变量。

struct Line lines;

这里,我不明白。你声明了变量lineS,它意味着很多行,那你为什么不使用数组或指针呢?

您的 "line" 结构和所有结构指针看起来像是额外的膨胀,并且您在多个位置分配数据碎片,导致代码变慢。考虑将整个内容重写为:

typedef struct 
{
    bool isNot;
    char letter;
} unit_t;

typedef struct
{
  unit_t unit[3][3];
} full_data_t;


full_data_t* full_data;
full_data = malloc(sizeof *full_data);
...
free(full_data);

如果您需要维度在 运行 时可变,那么 C 会变得有点不稳定。一种选择是使用灵活的数组成员:

typedef struct 
{
    bool isNot;
    char letter;
} unit_t;

typedef struct
{
  size_t x;
  size_t y;
  unit_t unit[];
} full_data_t;

full_data_t* full_data;
full_data = malloc(sizeof *full_data + sizeof(unit_t[x][y]));

不幸的是,这只声明了一个 "mangled" 二维数组,因为 unit 实际上是一个一维数组(弹性数组成员必须是一维数组)。您可以通过数组指针将其作为 2D 数组进行访问,定义良好且不违反任何别名规则,但语法变得有点邪恶:

unit_t (*unit_ptr)[y] = &full_data->unit;
...
unit_ptr[i][j]->letter = 'X';

完整示例:

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

typedef struct 
{
    bool isNot;
    char letter;
} unit_t;

typedef struct
{
  size_t x;
  size_t y;
  unit_t unit[];
} full_data_t;

int main(void)
{
  size_t x = 3;
  size_t y = 4;

  full_data_t* full_data;
  full_data = malloc(sizeof *full_data + sizeof(unit_t[x][y]));

  unit_t (*unit_ptr)[y] = &full_data->unit;

  for(size_t i=0; i<x; i++)
  {
    for(size_t j=0; j<y; j++)
    {
      unit_ptr[i][j].letter = 'A'+i*y+j; // whatever makes sense to use here
      printf("%c ", unit_ptr[i][j].letter);
    }
    printf("\n");
  }

  free(full_data);
  return 0;
}

另一种选择是使用 "mangled" 语法并直接访问 full_data->unit,即使它是一维数组,full_data->unit[i*y+j]。我认为可读性较差,但主要是风格问题。