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 *
更改为 line
或 unit
。
不要使用同名unit
、line
、fullData
之类的,应该使用不同的名字,例如:
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]
。我认为可读性较差,但主要是风格问题。
目标是让类型为 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 *
更改为 line
或 unit
。
不要使用同名unit
、line
、fullData
之类的,应该使用不同的名字,例如:
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]
。我认为可读性较差,但主要是风格问题。