当前位置: C语言 -- 专题 -- 弹性数组成员

弹性数组成员(二)

在绝大多数情况下弹性数组成员会被忽略,特别是结构的大小,除了可能具有尾部填充外,好像弹性数组成员省略了一样。

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;
主要参考资料:

1、ISO/IEC 9899:2018

2、en.cppreference.com : Array declaration

3、ibm.com : Flexible array members

4、pabloariasal.github.io : C++ - Initialization of Static Variables