柔性数组

  • 梦影无痕丶
  • 1 Minutes
  • February 20, 2018

题目引出

对一下数据结构中data的处理描述正确的是()

struct Node
{
    int size;
    char data[0];
}

A.data将会被编译成一个char * 类型指针

B.编译器认为这是一个长度为0的数组,并且会支持对于数组data的越界访问

C.编译器会默认将数组data的长度设置为1

D.以上全错

这里声明了一个长度为0的数组 data[0],该类型数组被称为柔性数组,也就是常说的动态数组。

什么是柔性数组

在C99标准下,允许结构体中最后一个成员变量是未知大小的数组,这就叫做柔性数组成员,但是在其前面必须包含至少一个其他成员。

柔性数组明确来说不算是结构体的成员,利用sizeof(结构体) 返回的值不包括柔性数组大小,包含柔性数组的结构体使用 malloc()进行内存的动态分配:

node *p=(ndoe *)malloc(sizeof(node)+100*sizeof(char))

再分配过内存后sizeof(*P)仍为4;

柔性数组用处

为了满足需要变长度的结构体,解决使用数组时内存的冗余和数组的越界问题,柔性数组必须放在结构的最后面。
对于编译器而言,柔性数组仅仅代表一个符号,一个不可修改的地址常量。
利用柔性数组,可以构造出变长结构体,如缓冲区,数据包等等;

柔性数组与指针的区别

  1. 位置:指针可以放在任何地方,柔性数组只能在变长结构体尾部。指针可以用在C++类中,但是变长结构体不可以,因为有些编译器会将一些额外信息放在类最后,如vptr或者虚基类,使用变长结构体会改变这些值。
  2. 内存占用:指针会占据一个指针大小的内存空间,柔性数组不占内存。
  3. 内存布局:指针指向内存和结构体内存可以是不连续的,柔性数组和结构体的内存必须是连续的。
  4. 内存释放:使用指针,需先释放指针指向内存的区域,再释放结构体内存,柔性数组直接释放整个结构体内存即可。