简体   繁体   English

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

[英]Malloc() a double nested struct in C

The goal is to have structs of type unit filling that array in struct line, and struct line filling the array in struct fullData so it essentially turns into a 2d array like so:目标是让 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

In my code, I am double nesting a struct, but don't know how to malloc a struct with an array of a struct inside of it, with an array of a struct inside of that one:在我的代码中,我双重嵌套了一个结构,但不知道如何 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;

This is the way that I am mallocing them now, but it seems wrong:这是我现在分配它们的方式,但它似乎是错误的:

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));

Firstly, it's not nested struct, it's the pointer to 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;

typedef struct fullData
{
     struct* table;
} fullData;

You use typedef for unit end line but you did not use them to declare the parameter in other struct.您将typedef用于unit结束line ,但您没有使用它们在其他结构中声明参数。 You should change struct * to line or unit .您应该将struct *更改为lineunit Do not use the same name unit , line fullData like that, you should use the difference names, for example:不要使用同名的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;

And

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

should change to:应改为:

fullData Block;
line lines;

Why do you think you malloc is failed?为什么你认为你的 malloc 失败了? It depends on how you use the variables in your code.这取决于您如何在代码中使用变量。

struct Line lines;

Here, i do not understand.在这里,我不明白。 You declared the variable lineS , it means many lines, so why do not you use array or pointer?您声明了变量lineS ,这意味着很多行,那么为什么不使用数组或指针呢?

Your "line" struct and all the struct pointers just seems like extra bloat and you allocate the data fragmented, at multiple locations, leading to slower code.您的“行”结构和所有结构指针看起来像是额外的膨胀,并且您在多个位置分配碎片数据,导致代码变慢。 Consider rewriting this whole thing into this:考虑将整个事情重写为:

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);

If you need the dimensions to be variable at run-time, then C turns a bit shaky.如果您需要在运行时改变尺寸,那么 C 会有点不稳定。 One option is to use a flexible array member:一种选择是使用灵活的数组成员:

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]));

Unfortunately this only declares a "mangled" 2D array, since unit is actually a 1D array (flex array members must be 1D arrays).不幸的是,这仅声明了一个“损坏的”二维数组,因为unit实际上是一个一维数组(弹性数组成员必须是一维数组)。 You can access it as a 2D array through an array pointer, well-defined without breaking any aliasing rules, but the syntax turns a bit evil:您可以通过数组指针将其作为 2D 数组访问,该指针定义明确且不违反任何别名规则,但语法变得有点邪恶:

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

Full example:完整示例:

#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;
}

Another option is to go with the "mangled" syntax and access full_data->unit directly even though it's a 1D array, with full_data->unit[i*y+j] .另一种选择是 go 使用“mangled”语法并直接访问 full_data->unit 即使它是一维数组,使用full_data->unit[i*y+j] Less readable in my opinion, but mostly a matter of style.在我看来,可读性较差,但主要是风格问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM