在C99标准中,新加入了变长数组和变长结构体
变长数组如下:其中a[n]就是变长数组,b[10]就是定长数组
int main() {
int b[10];
int n = 10;
int a[n];
}
该变长数组也可以对应于malloc的动态空间分配,等价于
int *a = malloc(n * sizeof(int));
二者的区别:
1.变长数组从栈上分配空间,malloc从堆上分配空间;
2.栈上分配和回收空间比堆上分配和回收空间要快;
3.当n过大时,可能导致栈溢出,但malloc分配时不会。
变长结构体:
变长结构体是将数组放在结构体末尾,通过给变长结构体动态分配内存时,额外分配更多的空间做buffer。值得注意的是,数组名是一个偏移量,本身不会占用空间,数组名代表的是一个不可修改的地址常量,但是我们对这个数组名指向的空间可以随意的指定。
变长结构体分配额外的空间做buffer的例子如下:
#include <stdio.h>
#include <stdlib.h>
struct v_struct {
int i;
int a[0];
};
int main()
{
v_struct *pv = (v_struct *)malloc(sizeof(v_struct)+sizeof(int)* 100);
pv->a[50] = 100;
printf("sizeof int is equal to %u\n", sizeof(int));
printf("sizeof v_struct is equal to %u\n", sizeof(v_struct));
printf("%u\n", sizeof(pv));
return 0;
}
运行结果为,两者的大小均为4
顺带打印了指针的大小,若机器是32寻址的,则指针大小为4字节,若机器是64位寻址的,则指针大小为8字节
变长结构体的作用:
1.变长结构体的变长部分通常可以用来作为buffer,缓存数据。
2.变长结构体的空间释放是很方便的,只需要free(pv), 而且不会造成内存泄露。
3.变长结构体使用起来更方便,不过,要小心越界。
为何不用指针代替变长结构体?
指针与变长结构体的区别:
1.位置方面:指针可以放在任何地方,但是变长结构体的变长部分一定要放在结构体的尾部;
2.内存占用方面:指针会占用一个指针大小的内存空间,但是变长数组不占内存,它只是一个占位符;
3.内存布局方面:指针指向的内存和结构体的内存可以是不连续的,但是变长部分和结构体的内存必须是连续的。
4.内存释放方面:使用指针,需要先释放指针所指向的内存,再释放整个结构体的内存,否则会造成内存泄漏;而使用变长结构体可以直接释放整个结构体的空间;
5.限制方面:指针可以用在C++的类中,而变长结构体不可以。因为有些编译器会将一些额外的信息放在类的最后,比如vptr或者虚基类的内容,使用了变长的类,就会把这部分的值改变,这种行为是未定义的。
参考博客:
http://blog.youkuaiyun.com/SKY453589103/article/details/51147505