struct中的可变长度数组

我正在用C语言编写应用程序(作为初学者),我正在努力在包含可变长度数组的结构中获取损坏的数据。 我发现在cprogramming.com上的论坛post以及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; 

有问题的是“命令”。 对于“命令”的任何给定实例(或任何正确的短语),将设置不同的字段,但在大多数情况下,尽管在不同的实例中设置相同的字段。

我遇到的问题是在尝试设置expected_next,name,sw1,sw2,size和data字段时。 这是数据领域正在腐败。 我正在为这样的结构分配内存;

 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) 

漂亮的印刷品发生在另一个function上;

 void pretty_print(char* line, command* cmd) 

我以为我做的事情是正确的,但显然不是。 据我所知,我构造了结构的其他实例好(并且我为这一个重复了这些方法)但是它们中不包含任何可变长度数组并且它们的漂亮打印看起来很好 – 这让我担心,因为它们可能也会被打破,但破损不太明显。

我正在编写的实际上是一个解析器,所以命令被传递到parse函数(它描述当前状态,给解析器提示接下来会发生什么),下一个命令(从输入“line”派生)是回。 “context”在解析函数的末尾是free-d,返回新命令 – 然后将其与输入的下一个“行”一起传递回“parse”。

任何人都可以建议为什么会发生这种情况?

非常感谢。

您必须分别分配desc和数据。

分配struct命令* cmd时,将为decs和data的指针分配内存。 描述和数据必须单独进行操作。

所以分配你的命令

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

然后为数据或desc分配内存
desc的例子:

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

为结构分配内存时,只有指针大小被分配给* desc。 正如有人已经指出的那样,你必须为空间(数组内容)指向内存分配内存。 我的答案的目的是显示略有不同的方式。 由于有一个指针* desc增加了一个单词(sizeof指针)的结构大小,你可以安全地在你的结构中有一个可变长度数组hack来减少结构大小。

这是你的结构应该是什么样子,请注意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′;

只有当成员位于结构的末尾,保存结构大小,保存指针间接时,才能使用此hack,如果数组长度是结构实例特定的,则可以使用此hack。