弹性数组成员(二)
在绝大多数情况下弹性数组成员会被忽略,特别是结构的大小,除了可能具有尾部填充外,好像弹性数组成员省略了一样。
struct data1 { int number; double arr[]; }; struct data2{ int number; int arr[]; }; struct data3{ int number; }; /*其他代码。*/ printf("int: %zu\n", sizeof(int)); printf("double: %zu\n", sizeof(double)); printf("struct data1: %zu\n", sizeof(struct data1)); printf("struct data2: %zu\n", sizeof(struct data2)); printf("struct data3: %zu\n", sizeof(struct data3));
将输出:
int: 4
double: 8
struct data1: 8
struct data2: 4
struct data3: 4
struct data1结构存在尾部填充,struct data2结构不存在尾部填充,所以struct data1结构大于struct data3结构,struct data2结构和struct data3结构大小相等。
弹性数组成员的偏移应被保留。
struct data1 { int number; double arr[]; }; struct data2{ int number; int arr[]; }; /*其他代码。*/ printf("offsetof(struct data1, arr): %zu\n", offsetof(struct data1, arr)); printf("offsetof(struct data2, arr): %zu\n", offsetof(struct data2, arr));
将输出:
offsetof(struct data1, arr): 8
offsetof(struct data1, arr): 4
包含弹性数组成员的结构声明后,一个典型的使用方法是使用动态内存分配,例如:
struct data { int number; double arr[]; }; /*其他代码。*/ int m; //m表示数组元素数。 /*其他代码。*/ struct data *ptr = malloc(sizeof(struct data) + sizeof(double [m]));
如果动态内存分配成功,大多数情况下,指针ptr和下面的指针相同。
struct data { int number; double arr[m]; } *ptr;
动态内存分配成功后,就可以对数组进行一些操作,例如给数组元素赋值。
struct data *ptr = malloc(sizeof(struct data) + sizeof(double [3])); ptr->arr[0] = 3.14; ptr->arr[1] = 2.36; ptr->arr[2] = 6.24;主要参考资料:
2、en.cppreference.com : Array declaration
3、ibm.com : Flexible array members
4、pabloariasal.github.io : C++ - Initialization of Static Variables