我在变量结构中有可变大小的结构。走每个子表的好方法是什么?缓冲区是字节打包的,可在“地址”处获得。不需要malloc。无法在while循环中进行索引,使用表大小进行偏移是唯一的选择吗?
void walk_master_table (ulong address)
{
int count=0;
Master_table* masterTable = (Master_table*)address;
while(masterTable->subTables[count].subTable1.length)
{
//do some processing;
// advance to next sub table
count ++; /* <-- I cannot do this because the offset is not */
/*guaranteed and the buffer is byte-packed*/
}
}
struct Master_table
{
uint Total_MasterTable_Length;
struct SUB_TABLES subTables[1];
}
struct SUB_TABLES
{
union {
struct subTable1;
struct subTable2;
struct subTable3;
struct subTable4;
char buffer[128];
};
}
/*each subtable is of different size.*/
struct subTable1
{
uint thisTable_length;
char [xx];
}
struct subTable1
{
uint thisTable_length;
char [yy];
}
struct subTable3
{
uint thisTable_length;
char [zz];
}
答案 0 :(得分:0)
首先,将指针作为整数值传递是一种不好的形式。如果您想避免命名特定类型,请使用void *
,但如果您总是要转换为特定指针类型,那么您应该声明该参数具有该类型。
更重要的是,您似乎正在使用现在称为struct
的灵活数组成员的非标准形式。当您访问masterTable->subTables[count]
且count
大于1时,您的代码会显示未定义的行为。在C99中标准化的类似形式(已定义更多count
值的行为)将要求您声明{ {1}}有点不同:
struct Master_table
通常的用法是为这些对象动态分配内存,足够用于固定大小的部分加上灵活数组所需的许多元素。然后允许通过灵活的阵列成员访问分配的空间,前提是您不能访问为其分配的空间。
但是,您的代码注释到,通过将索引递增到struct Master_table
{
uint Total_MasterTable_Length;
struct SUB_TABLES subTables[]; /* no declared size */
}
来访问连续的子表是不正确的,如果正确的话,似乎表明从地址Master_table.subTables
开始的数据实际上并不构成<{1}}的有效表示(如您所声明的那样),是否为灵活成员。
数组是固定大小对象的序列。您的address
是一个有效的数组元素类型,但它不是可变大小的。由于它只有一个成员,因此它是该成员(联合)的大小,并且union是其最大成员的大小。每个struct Master_table
对象都是那么大。
如果您对子表实际拥有的是一系列struct SUB_TABLES
s各种类型struct SUB_TABLES
- struct
,包装没有间隙,且这些子表具有不同的大小,则表示不数组struct subTable1
。而且,如果你只有你提供的数据,我也不知道如何在运行时弄清楚它是什么。
如果您的子表格数据严格属于{struct subTable4
,struct SUB_TABLES
}格式,那么您应将table_length
声明为char[table_length]
。您将需要使用强制转换和指针算法来处理数据。您也许可以使用具有灵活成员的子表subTables
类型来帮助,但将void *
声明为此类数组不会产生有用的效果。