C++ 变长数组
200 Words|Read in about 1 Min|本文总阅读量次
Android源码中有一些经常会遇到的c++基础的内容,笔者对C++ 变长数组进行简单熟悉。
C++ 变长数组
在Android系统源码中,会经常出现变长数组,类似如下的结构
1//bionic/libc/system_properties/include/prop_area.h
2struct prop_bt {
3 uint32_t namelen;
4 atomic_uint_least32_t prop;
5 atomic_uint_least32_t left;
6 atomic_uint_least32_t right;
7 atomic_uint_least32_t children;
8 char name[0];
9
10 prop_bt(const char* name, const uint32_t name_length) {
11 this->namelen = name_length;
12 memcpy(this->name, name, name_length);
13 this->name[name_length] = '\0';
14 }
15
16 private:
17 BIONIC_DISALLOW_COPY_AND_ASSIGN(prop_bt);
18};
可以看到除去namelen
和几个原子操作的变量,最后是一个char name[0]
的写法,这种写法就是变长数组的用法。
变长数组作用
变长数组又叫柔性数组。让数组长度是可变的,根据需要进行分配。方便操作,节省空间。不需要一开始定义,需要的时候再分配大小。
1#include <iostream>
2#include<string.h>
3
4typedef struct Data
5{
6 int namelen;
7 char name[0];
8}Data_t;
9
10int main()
11{
12 char str[] = "IronMan";
13 int nLen = strlen(str);
14 printf("no malloc struct size (%u), nLen(%u) \n", sizeof(Data_t), nLen);
15
16 Data_t *myData = (Data_t*)malloc(sizeof(Data_t) + nLen);
17 myData->namelen = nLen;
18 memmove(myData->name, str, nLen + 1);
19 printf(" Data struct len(%d), name(%s) \n", myData->namelen, myData->name );
20
21 free(myData);
22 return 0;
23}
结果输出
结论:可以看到结构体的大小仅只有namelen
的大小。分配完结构体的堆区之后,堆区的前4个字节是namelen
,后面都是变长数组的内容。
进一步探讨
上述的
name[0]
也可以写成name[]
,同样不占用空间,且地址紧跟在结构后面。但是如果写成char *name
,那么这样就会作为指针,占用4个字节,地址不在结构之后,整个结构体就包含指针的大小。 另外采用char *name
,需要进行二次分配,操作比较麻烦,很容易造成内存泄漏。而直接采用变长的数组,只需要分配一次,然后进行取值即可以。