具有可变长度数组的 c 结构的静态分配

Static allocation of c struct with variable length array

提问人:wstuchbury-pathtrack 提问时间:9/11/2023 更新时间:9/11/2023 访问量:57

问:

我想使用一个结构来存储一个可变长度的字节数组(UART 消息)和一些其他信息/标志,例如长度、消息的作用等。我定义了一个结构:

typedef struct Message {
    int length;
    int otherInfo;
    char* bytes;
} Message;

并且想要静态分配这些结构的数组,这些结构将对应于某些消息(我有一个枚举来定义索引):

Message messages[] = {
    [UART_MESSAGE_TO_DO_X] = {
        .length = 16,
        .otherInfo = 10,
        .bytes = {
            0xB5, 0x62, //array of bytes that does X
            0x06, 0x01, 
            0x08, 0x00, 
            0xF0, 0x00, 
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
            0xFF, 0x23 
        }
    },
    [UART_MESSAGE_TO_DO_Y] = {
        .length = 20,
        .otherInfo = 15,
        .bytes = {
            0xB5, 0x62, //array of bytes that does Y
            0x06, 0x41, 
            0x0C, 0x00, 
            0x00, 0x00, 0x03, 0x1F, 0xC5, 0x90, 0xE1, 0x9F, 0xFF, 0xFF, 0xFE, 0xFF, 
            0x45, 0x79 
        }
    }
}

但是,这给出了一个警告“标量初始值设定项中的多余元素”,我已经查找并看到了动态分配可变大小数组然后分配为指针的解决方案,但是我想静态分配,因为值永远不会改变,并且我正在使用资源有限的微处理器。我知道长度未知的可变长度数组不能静态分配,但是在我的情况下,每个数组的长度是已知的并且是恒定的,只是 stuct 实例之间的长度不同。

c 结构 分配

评论

3赞 KamilCuk 9/11/2023
with variable length array可变长度数组在哪里?
0赞 Gerhardh 9/11/2023
.bytes = {... }这将初始化结构的数组成员,但您只有一个指针元素。这不是一个可变长度的数组。
1赞 David Ranieri 9/11/2023
我认为您的意思是灵活的数组成员(但它们是形式,不能用作数组元素)。你能试试复合文字吗?char bytes[].bytes = (char []) {...}
0赞 Lundin 9/12/2023
UART 消息永远不会是未知的或可变的。程序可以合理处理的最大缓冲区大小。要么分配足够的静态内存来处理这种情况,要么你的程序无法处理 UART,就这么简单。这个大小是确定性的,可以在设计程序时通过实时计算等来确定。

答:

2赞 KamilCuk 9/11/2023 #1

char* 字节;

这是一个正常的指针。分配阵列。分配指针

static char array[] = {
       0xB5, 0x62, //array of bytes that does X
       0x06, 0x01, 
       0x08, 0x00, 
       0xF0, 0x00, 
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
       0xFF, 0x23 
};    
static Message messages[] = {
    [UART_MESSAGE_TO_DO_X] = {
        .length = 16,
        .otherInfo = 10,
        .bytes = array,
    },
};

或者使用复合文字 https://en.cppreference.com/w/c/language/compound_literal .注意复合文字的生存期。

static Message messages[] = {
    [UART_MESSAGE_TO_DO_X] = {
        .length = 16,
        .otherInfo = 10,
        .bytes = (char[]){
            0xB5, 0x62, //array of bytes that does X
            0x06, 0x01, 
            0x08, 0x00, 
            0xF0, 0x00, 
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
            0xFF, 0x23 
        }
    },
};

“可变长度数组”是一个定义的术语 - https://en.cppreference.com/w/c/language/array#Variable-length_arrays 。您的数组大小似乎是恒定的。

如果所有数据都保持不变,请考虑添加。const

评论

0赞 drdoof 9/11/2023
谢谢,复合文字正是我想要的,我只是不知道它的名字。我相信生存期不应该是一个问题,因为我在全局范围内分配它,据我所知,在 C 中它将被赋予静态存储持续时间,在 C++ 中,这似乎具有未定义的行为。
0赞 chux - Reinstate Monica 9/11/2023
K,“分配指针”比“用指针初始化”更好,因为赋值在 C 中略有不同
0赞 Lundin 9/12/2023
好吧,我相信你已经知道等等是一个菜鸟错误。 在处理原始数据时,根本不应该使用。请修复。char x = 0xB5;char