struct中的可变长度数组

Tom*_*Tom 5 c arrays malloc struct

我正在用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;
Run Code Online (Sandbox Code Playgroud)

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

我遇到的问题是在尝试设置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);
Run Code Online (Sandbox Code Playgroud)

但是当我(漂亮地)打印生成的cmd时,数据字段的中间似乎是随机垃圾.我已经介绍了gdb,可以看到正确的数据被加载到该字段中.它似乎只有当命令传递给另一个函数时它才会被破坏.这个代码在一个函数内部调用;

command* parse(char *line, command *context)
Run Code Online (Sandbox Code Playgroud)

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

void pretty_print(char* line, command* cmd)
Run Code Online (Sandbox Code Playgroud)

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

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

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

非常感谢.

Nei*_*lue 11

为结构分配内存时,只有指针大小被分配给*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;
Run Code Online (Sandbox Code Playgroud)

现在,1.为包含数组大小的命令分配内存:

 command *cmd = malloc(sizeof(command) + desc_length);
Run Code Online (Sandbox Code Playgroud)
  1. 使用desc:

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

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


小智 9

您必须单独分配desc和数据.

分配struct命令*cmd时,会为decs和data的指针分配内存.描述和数据必须单独进行索引.

所以分配你的命令

command *cmd =  malloc(sizeof(command));
Run Code Online (Sandbox Code Playgroud)

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

cmd->desc = malloc( sizeof(char )*100);
Run Code Online (Sandbox Code Playgroud)