Массивы переменной длины в структуре

Я пишу приложение на C (как новичок), и я изо всех сил пытаюсь получить поврежденные данные внутри структуры, содержащей массив переменной длины. Я нашел похожие проблемы, описанные в сообщениях форума на cprogramming.com, а также на cert.og / secure-coding. Я думал, что нашел правильное решение, но, похоже, нет.

Структура выглядит так:

typedef struct { int a; int b; } pair; typedef struct { CommandType name; pair class; pair instr; pair p1; pair p2; pair p3; CommandType expected_next; char* desc; int size; pair sw1; pair sw2; pair* data; } command; 

С проблематичным является «команда». Для любого данного экземпляра (или, что бы там ни была правильная фраза) «команды» были установлены разные поля, хотя в большинстве случаев одни и те же поля задаются, хотя и в разных случаях.

Проблема заключается в том, что вы пытаетесь установить поля ожидаемого_имя, имени, sw1, sw2, размера и данных. И это поле данных становится коррумпированным. Я выделяю память для такой структуры;

 void *command_malloc(int desc_size,int data_size) { return malloc(sizeof(command) + desc_size*sizeof(char) + data_size*sizeof(pair)); } command *cmd; cmd = command_malloc(0, file_size); 

Но когда я (довольно) печатаю полученный cmd, середина поля данных оказывается случайным мусором. Я прошел через gdb и вижу, что правильные данные загружаются в поле. Похоже, что только тогда, когда команда передается другой функции, которая становится поврежденной. Этот код вызывается внутри функции, такой как;

 command* parse(char *line, command *context) 

И симпатичная печать происходит в другой функции;

 void pretty_print(char* line, command* cmd) 

Я думал, что делаю все правильно, но, видимо, нет. Насколько я могу судить, я строю другие экземпляры структуры в порядке (и я дублировал эти подходы для этого), но они не содержат в них массив переменной длины, и их красивые отпечатки выглядят хорошо – что касается меня, потому что они также может быть нарушена, но поломка менее очевидна.

То, что я пишу, на самом деле является парсером, поэтому команда передается в функцию синтаксического анализа (которая описывает текущее состояние, давая подсказки парсеру, что ожидать дальше), а следующая команда (полученная из входной «строки») вернулся. «context» – это free-d в конце функции parse, которую возвращает новая команда, которая затем будет передана обратно в «parse» со следующей «строкой» ввода.

Может ли кто-нибудь предложить что-нибудь, почему это может произойти?

Большое спасибо.

Вы должны выделить desc и данные отдельно.

Когда вы выделяете вашу команду struct * cmd, память выделяется для ваших указателей делений и данных. Описание и данные необходимо разделить отдельно.

Поэтому выделите свою команду

 command *cmd = malloc(sizeof(command)); 

затем распределите память для данных или по порядку
пример для desc:

 cmd->desc = malloc( sizeof(char )*100); 

Когда вы выделяете структуру памяти, только размер указателя распределяется по * desc. Вы должны выделить память для дескрипторов пространства (содержимого массива), как уже указывал кто-то. objective моего ответа – показать немного другой способ сделать это. Поскольку указатель * desc увеличивает размер структуры по слову (sizeof pointer), вы можете смело иметь хаус переменной длины в структуре, чтобы уменьшить размер структуры.

Вот как выглядит ваша структура, обратите внимание, что desc [] был снесен до конца структуры:

 typedef struct { CommandType name; pair class; pair instr; pair p1; pair p2; pair p3; CommandType expected_next; int size; pair sw1; pair sw2; pair* data; char desc[]; } command; 

Теперь, 1. Выделите память для команды, которая также включает размер массива:

  command *cmd = malloc(sizeof(command) + desc_length); 
  1. Используйте desc:

    cmd-> desc [desc_length -1] = ‘\ 0’;

Этот хак работает только в том случае, если элемент находится в конце структуры, сохраняет размер структуры, сохраняет указатель на указатель, может использоваться, если длина массива является специфичной для экземпляра структуры.