在struct中作为数组大小变量

时间:2010-11-05 14:18:36

标签: c arrays data-structures

我在程序中实现了一个文件结构,但对于结构中的某些数组,我不知道它的大小。数组的大小存储在另一个变量中,但在填充结构之前它是未知的。

struct Vertex {
    float x;
    float y;
    float z;
};
struct myFile {
    ulong nVertices;
    Vertex vertices[nVertices];
};

出现错误:“错误C2065:'nVertices':未声明的标识符”。

2 个答案:

答案 0 :(得分:14)

您应该在结构中存储指针:

Vertex *vertices;

然后在运行时分配内存:

myFile f;
f.vertices = malloc(nVertices * sizeof(Vertex));
if (f.vertices == 0)
    handle_out_of_memory();

f.nVertices = nVertices;

完成后请记得释放内存:

free(f.vertices);

答案 1 :(得分:10)

C99引入了“灵活的阵列成员”,这可能是您想要使用的。您的代码最终看起来非常像@frast建议的代码,但略有不同。

  

§6.7.2.1结构和联合说明符

     

结构或联合不得包含不完整或功能类型的成员(因此,   结构不应包含自身的实例,但可以包含指向实例的指针   它本身),除了具有多个命名成员的结构的最后一个成员   可能有不完整的数组类型;这样的结构(和任何包含的结合,可能   递归地,这种结构的成员不应该是结构的成员或者   数组的元素。

     

[...]

     

作为一种特殊情况,具有多个命名成员的结构的最后一个元素可以   有一个不完整的数组类型;这被称为灵活的阵列成员。有两个   异常,灵活的数组成员被忽略。首先,结构的大小应为   等于替换其他相同结构的最后一个元素的偏移量   具有未指定长度数组的灵活数组成员。 106)其次,当a。 (或 - >)   operator有一个左操作数,它是一个带有灵活数组成员的结构(指向)   并且右边的操作数命名该成员,它的行为就像该成员被替换一样   最长的数组(具有相同的元素类型),不会构成结构   大于被访问的对象;数组的偏移量应保持为   灵活的阵列成员,即使这与替换阵列的成员不同。如果这   数组没有元素,它的行为好像它有一个元素,但行为是   如果尝试访问该元素或生成过去的指针,则为undefined   它

     

示例假设所有数组成员在声明之后对齐相同:

struct s { int n; double d[]; };
struct ss { int n; double d[1]; };
     

三个表达式:

sizeof (struct s)
offsetof(struct s, d)
offsetof(struct ss, d)
     

具有相同的值。结构struct具有灵活的数组成员d。

     

如果sizeof(double)为8,则在执行以下代码后:

struct s *s1;
struct s *s2;
s1 = malloc(sizeof (struct s) + 64);
s2 = malloc(sizeof (struct s) + 46);
     

并假设对malloc的调用成功,s1和s2指向的对象的行为就像是   标识符已声明为:

struct { int n; double d[8]; } *s1;
struct { int n; double d[5]; } *s2;
     

进一步成功完成作业后:

s1 = malloc(sizeof (struct s) + 10);
s2 = malloc(sizeof (struct s) + 6);
     然后他们表现得好像声明是:

struct { int n; double d[1]; } *s1, *s2;
     

double *dp;
dp = &(s1->d[0]); // valid
*dp = 42; // valid
dp = &(s2->d[0]); // valid
*dp = 42; // undefined behavior
     

作业:

*s1 = *s2;
     

仅复制成员n而不复制任何数组元素。类似地:

struct s t1 = { 0 }; // valid
struct s t2 = { 2 }; // valid
struct ss tt = { 1, { 4.2 }}; // valid
struct s t3 = { 1, { 4.2 }}; // invalid: there is nothing for the 4.2 to initialize
t1.n = 4; // valid
t1.d[0] = 4.2; // undefined behavior
     

106)未指定长度以允许实现可能使数组成员不同   根据它们的长度进行对齐。

该示例来自C99标准。