我已经阅读并查看了一些灵活数组成员的示例,但我不确定如何添加和读取此可变长度数组的元素。
typedef struct School {
char *name;
char *courses[]; //Flexible Array Member
} School;
1)有人可以给我看一个例子,说明如何将元素添加到这个挠性长度成员并在存储后打印出来。
2)我也想知道如何正确定位它。根据我所读到的有关灵活阵列成员的内容,我们需要为灵活阵列成员添加更多空间,而不能只使用sizeof(School);
。我唯一的问题是我怎么知道为该灵活成员增加了多少。
您应该修改struct
以添加分配结构中存在的课程数量:
typedef struct School {
char *name;
int ncourses;
char *courses[]; //Flexible Array Member
} School;
假设您有 2 所学校,一所有 3 门课程,一所有 2 门课程。 您可以按以下方式分配结构:
School *mc = malloc(offsetof(struct School, courses) + 3 * sizeof(char *));
mc->name = strdup("Math College");
mc->ncourses = 3;
mc->courses[0] = strdup("Math 101");
mc->courses[1] = strdup("Math 102");
mc->courses[2] = strdup("Math 103");
School *ps = malloc(offsetof(struct School, courses) + 2 * sizeof(char *));
ps->name = strdup("Psycho School");
ps->ncourses = 2;
ps->courses[0] = strdup("Psycho 101");
ps->courses[1] = strdup("Unknown 404");
如您所见,访问变量数组的元素与任何其他数组元素一样。 malloc
调用为位于结构末尾的结构成员和数组元素(此处char *
指针)分配适当的大小(以字节为单位)。
您可以使用泛型函数来分配和初始化此类结构:
School create_school(const char *school_name, int ncourses, char *courses[]) {
School *sp = malloc(offsetof(struct School, courses) + ncourses * sizeof(char *));
sp->name = strdup(school_name);
sp->ncourses = ncourses;
for (int i = 0; i < ncourses; i++) {
sp->courses[i] = strdup(courses[i]);
}
return sp;
}
计算所需结构大小的确切公式为:
size_t need = offsetof(struct School, courses) + num_courses * sizeof(char *);
请注意使用offsetof
。有些人使用sizeof
,但由于结构填充,这可能会带来内存开销。
本质上,该技术是为结构体以及最后一个数组的元素动态分配足够的内存。
School *data = malloc(sizeof(*data) + number * sizeof(*(data->courses)));
for (i = 0; i < number; ++i)
{
const char hello[] = "Hello";
data->courses[i] = malloc(strlen(hello) + 1)); /* sizeof char is 1 by definition */
strcpy(courses[i], hello);
}