【35】C语言 | 柔性数组
迪丽瓦拉
2024-05-22 04:59:39
0

目录

柔性数简介

柔性数组的特点

柔性数组的优势


柔性数简介

  • C99中,结构中的最后一个元素允许是未知大小的数组,这就叫做[柔性数组]成员
  • 在一个结构体的最后, 申明一个长度为0的数组, 就可以使得这个结构体是可变长的. 对于编译器来说, 此时长度为0的数组并不占用空间, 因为数组名本身不占空间, 它只是一个偏移量, 数组名这个符号本身代表了一个不可修改的地址常量

举例:

struct S
{int n;int arr[0];  //大小是未知的//int arr1[]; //大小是未知的return 0;
};

柔性数组的特点

  • 结构中的柔性数组成员前面必须至少一个其他成员
  • sizeof 返回的这种结构大小不包括柔性数组的内存。
  • 包含柔性数组成员的结构用malloc (函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。

举例:

方法一

#include
struct S
{int n;int arr[0];
};
int main()
{//期望arr的大小是10个整形struct S*ps = (struct S*)malloc(sizeof(struct S) + 10*sizeof(int));ps->n = 10;int i = 0;for(i=0; i<10; i++){ps->arr[i] = i;}//增加struct S* ptr = (struct S*)realloc(ps,sizeof(struct S)+20*sizeof(int));if(ptr !=NULL){ps = ptr;}//使用//释放free(ps);ps = NULL;return 0;
}

方法二

#include
struct S
{int n;int* arr;
};
int main()
{struct S* ps = (struct S*)malloc(sizeof(struct S));if(ps == NULL)return 1;ps->n = 10;ps->arr = (int*)malloc(10*sizeof(int));if(ps->arr == NULL)return 1;int i = 0;for(i=0; i<10; i++){ps->arr[i] = i;}//增加int*ptr = (int*)realloc(ps->arr,20*sizeof(int));if(ptr != NULL){ps->arr = ptr;}//使用//释放free(ps->arr);ps->arr = NULL;free(ps);ps = NULL;return 0;
}

柔性数组的优势

上述代码1和代码2可以完成同样的功能,但是方法1的实现有两个好处

第一个好处是:方便内存释放
如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配并把整个结构体返回给用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存一次性分配好了,并返回给用户一个结构体指针,用户做一次free就可以把所有的内存也给释放掉
第二个好处是:这样有利于访问速度
连续的内存有益于提高访问速度,也有益于减少内存碎片(其实,我个人觉得也没多高了,反正你跑不了要用做偏移量的加法来寻址

柔性数组需要注意

  • (1)必须是结构体的最后一个成员
  • (2)柔性数组之上,需要有其他的成员(结构体中不能只有一个柔性数组)
  • (3)sizefo返回的结构体的大小不包括柔性数组的内存(如果是char data[1]就会有一个单位的空间)

相关内容