柔性数组
c语言并没有柔性数组这个概念,但他又是实际存在的,结构体中最后一个成员是数组,且未规定内存大小,即可理解为柔性数组
柔性数组的特点
1.结构体中柔性数组的成员前面至少有一个其他成员
2.sizeof计算结构体大小是不包含柔性数组的内存
3.包含柔性数组成员的结构应用malloc进行开辟内存空间,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小
1.
1 2 3 4 5
| struct S { int a; int arr[]; };
|
此时arr就是一个柔性数组
1 2 3 4 5 6 7 8 9 10
| struct S { int a; int arr[]; }; int main() { printf("%d", sizeof(s)); return 0; }
|
运行的结果是
也就是不包括柔性数组的大小,只有他前面成员的大小
2.柔性数组应该用malloc进行开辟空间,而不是直接对其进行赋值
1 2 3 4 5 6 7 8 9 10 11 12
| struct S { int a; int arr[]; }; int main() { struct S s={0}; printf("%d", sizeof(s)); return 0; }
|
正确的使用应该是这样的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| struct S { int a; int arr[]; };
int main() { struct S* ptr = (struct S*)malloc(sizeof(struct S) + 10*sizeof(int)); ptr->a = 10; int i = 0; for (i = 0; i < 10; i++) { ptr->arr[i] = i; } struct S* ps = (struct S*)realloc(ptr, sizeof(struct S) + 20 * sizeof(int)); if (ps != NULL) { ptr = ps; } printf("%d", ptr->arr); free(ptr); ptr = NULL; return 0; }
|
可能会有人认为将结构体中的数组改为指针也可以
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| struct s { int a; int *arr; }; int main() { struct s* ps = (struct s*)malloc(sizeof(struct s)); if (ps == NULL) { return 1; } ps->a = 10; ps->arr = (struct s*)malloc(sizeof(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; }
|
但实际上他malloc开辟了两次空间,留了过多的内存碎片,使得内存的利用率降低,
优势.方便开辟。方便释放