Mallo c () структура с двойным вложением в C - PullRequest
0 голосов
/ 24 апреля 2020

Цель состоит в том, чтобы иметь структуры единиц типа, заполняющие этот массив в struct line, и struct line, заполняющие массив в struct fullData, чтобы он по существу превращался в 2d массив следующим образом:

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

В моем код, я двойное вложение структуры, но не знаю, как mallo c структура с массивом структуры внутри него, с массивом структуры внутри этого:

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

Ответы [ 2 ]

1 голос
/ 24 апреля 2020

Ваша структура "line" и все указатели struct просто кажутся лишними, и вы размещаете фрагментированные данные в нескольких местах, что приводит к замедлению работы кода. Попробуйте переписать всю эту вещь так:

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

К сожалению, это объявляет только «искаженный» 2D-массив, поскольку unit на самом деле является одномерным массивом (члены гибкого массива должны быть одномерными массивами). Вы можете получить к нему доступ как к двумерному массиву через указатель массива, четко определенный, не нарушая никаких правил наложения имен, но синтаксис становится немного злым:

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

Другой вариант - go с "искаженным" синтаксисом и прямой доступ к модулю full_data->, даже если это одномерный массив, с full_data->unit[i*y+j]. Менее читабельным, на мой взгляд, но в основном вопрос стиля.

1 голос
/ 24 апреля 2020

Во-первых, это не вложенная структура, это указатель на структуру.

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 для unit end line, но вы не использовали их для объявления параметра в другом STRUCT. Вы должны изменить 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;

Почему вы думаете, что Мальло c провалился? Это зависит от того, как вы используете переменные в вашем коде.

struct Line lines;

Здесь я не понимаю. Вы объявили переменную lineS, она означает много строк, так почему бы вам не использовать массив или указатель?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...