「柔性数组定义」:在结构体中,至少含有两个成员,其中最后一个成员必须是空数组。比如下面的例子:一个通过柔性数组来实现的含有长度信息的字符串。
struct string{ int len; // 用来存储buf中字符串的长度 char buf[]; // 用来存储字符串 }; sizeof(struct string) == sizeof(int); // 1
我们实现了一个flexible array
,里面含有一个int
型的成员,同时含有一个char
型的空数组。该结构体的大小等于除去最后一个空数组的大小,在这里等于int
的大小。
在使用的时候可以通过动态内存来进行内存的分配。
// 这里我们存储10个char型的字符 // 首先需要先申请内存 // 大小为 结构体的大小 + 需要放入的字符串的大小 + 最后一个字符\0的大小 int len = 10; struct string* s = malloc(sizeof(struct string) + sizeof(char) * (len + 1)); strcpy(s->buf,"0123456789"); s->len = len; s->buf[len] = 0; printf(s->buf); // 0123456789 free(s);
在动态内存申请的时候,每次都多申请一个char的空间,可以将我们的字符串与c语言原生字符串做到兼容,也就是说,我们的字符串也可以使用c语言标准库中的函数,比如strlen
。
写到这里,可能有的同学还有另外一种实现的方法,下面先给出代码:
struct string{ int len; char* buf; }
通过来设置记录指针来将我们的字符串去连接一个真正的c语言原生字符串,在使用的时候,需要我们这样做:
int len = 10; struct string* s = malloc(sizeof(struct string)); char* ps = malloc(sizeof(char) * (len + 1)); strcpy(ps,"0123456789"); ps[len] = 0; s->buf = ps; s->len = len; printf(s->buf); free(s); free(ps);
可以发现,这里我们需要申请两块内存,在释放的时候也需要对两块内存进行释放。这在实现上是可以接受的,但是,在内存的效率是不如第一种的。
主要的原因在于,第一种方法在申请的内存是一块,也就是说一定是连续的,但是第二种需要申请两块内存,在访问的时候,由于不是连续的,与第一种相比,可能会有多次的读操作,也就会导致效率下降。