以下结构的大小是多少?
CPP
struct employee { int emp_id; int name_len; char name[0]; }; |
4+4+0=8字节。 那么“名称[0]”的大小呢。在gcc中,当我们创建一个长度为零的数组时,它被认为是不完整类型的数组,这就是为什么gcc将其大小报告为“0”字节。这种技术被称为“结构黑客”。当我们在结构内部创建长度为零的数组时,它必须是(而且只是)结构的最后一个成员。很快我们将看到如何使用它。 “Struct Hack”技术用于在结构中创建可变长度的构件。在上面的结构中,“name”的字符串长度不是固定的,所以我们可以使用“name”作为可变长度数组。 让我们看看下面的内存分配。
struct employee *e = malloc(sizeof(*e) + sizeof(char) * 128);
相当于
CPP
struct employee { int emp_id; int name_len; char name[128]; /* character array of size 128 */ }; |
低于内存分配
struct employee *e = malloc(sizeof(*e) + sizeof(char) * 1024);
相当于
CPP
struct employee { int emp_id; int name_len; char name[1024]; /* character array of size 1024 */ }; |
注意:由于名称是字符数组,在malloc中,我们可以直接使用“128”,而不是“sizeof(char)*128”。sizeof用于避免混淆。 现在我们可以使用和指针相同的“名称”。例如
e->emp_id = 100;e->name_len = strlen("Geeks For Geeks");strncpy(e->name, "Geeks For Geeks", e->name_len);
当我们如上所述分配内存时,编译器将分配内存来存储“emp_id”和“name_len”,再加上连续内存来存储“name”。当我们使用这种技术时,gcc保证“name”将获得连续内存。 显然还有其他方法可以解决这个问题,一种是我们可以使用字符指针。但不能保证字符指针将获得连续内存,我们可以利用这种连续内存。例如,通过使用这种技术,我们可以通过使用单个malloc和free调用来分配和释放内存(因为内存是有传染性的)。这样做的另一个好处是,假设我们想要写入数据,我们可以通过使用单个“write()”调用来写入整个数据。例如
write(fd, e, sizeof(*e) + name_len); /* write emp_id + name_len + name */
如果我们使用字符指针,那么我们需要两个写调用来写数据。例如
write(fd, e, sizeof(*e)); /* write emp_id + name_len */write(fd, e->name, e->name_len); /* write name */
注意:在C99中,有一个叫做“灵活数组成员”的功能,其工作原理与“结构黑客”相同 本文由 纳伦德拉·康拉尔卡 。如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请发表评论