(文章目錄)
前言
也許你從未聽說過柔性數組這個概念,但它确實存在。C99中,結構體中的最後一個成員允許是未知大小的數組,這就叫柔性數組成員。
1.柔性數組是什麼?
結構體中的最後一個成員允許是未知大小的數組,這就叫柔性數組成員。
struct S
{
int n;
int arr[];//未知大小的柔性數組成員,數組的大小是可以調整的
};
int main()
{
struct S s;
printf("%d\n",sizeof(s));//計算次結構體大小輸出 4 并沒有計算arr數組的大小
return 0;
}
我們建立的柔性數組一般用法:
struct S
{
int n;
int arr[];
};
int main()
{
//建立一個結構體指針ps,給它動态配置設定4+20個位元組的記憶體
struct S* ps = (struct S*)malloc(sizeof(struct S) + 5*sizeof(int));
return 0;
//可以使用arr這個柔性數組
free(ps);
ps = NULL;
return 0;
}
2.柔性數組有哪些好處呢?
我們先看如下兩個代碼
- 代碼1 使用柔性數組實作功能
struct S
{
int n;
int arr[];
};
int main()
{
//建立一個結構體指針ps,給它動态配置設定4+20個位元組的記憶體
struct S* ps = (struct S*)malloc(sizeof(struct S) + 5*sizeof(int));
ps->n = 100;
int i = 0
for (i=0;i<5;i++)
{
ps->arr[i] = i;//給數組arr指派 0 1 2 3 4
}
free(ps);
ps = NULL;
return 0;
- 代碼2 使用常用的嵌套指針的方式實作功能
struct S
{
int n;
int* arr;
};
int main()
{
struct S* ps = (struct S*)malloc(sizeof(struct S));
ps->arr = malloc(5*sizeof(int));
int i = 0
for (i=0;i<5;i++)
{
ps->arr[i] = i;//給數組arr指派 0 1 2 3 4
}
//釋放兩個開辟的記憶體
free(ps->arr);
ps->arr = NULL;
free(ps);
ps = NULL;
return 0;
代碼1 和 代碼2 都可以實作arr數組大小的靈活調整。但是代碼1有兩個好處:
-
友善記憶體的釋放
如果我們的代碼是在一個給别人用的函數中,你在裡面做了二次記憶體配置設定,并把整個結構體傳回給使用者,使用者調用free可以釋放結構體但是使用者并不知道這個結構體内的成員也需要free,是以你不能指望使用者來發現這個事。是以我們把結構體的記憶體以及成員要的記憶體一次性配置設定好了,并傳回給使用者一個結構體指針,使用者做一次free就可以把所有記憶體給釋放調。
-
提高通路速度
連續的記憶體有利于提高通路速度,也有利于減少記憶體碎片
3.柔性數組特點
- 結構體中的柔性數組成員前面必須有一個其他成員
- sizeof 傳回的這種結構大小不包括柔性數組的内容
- 包含柔性數組的成員結構用malloc()函數進行記憶體的動态配置設定,并且配置設定的記憶體應該大于結構體的大小,以适應柔性數組的預期大小。
struct S
{
int n;//柔性數組成員前面必須存在的成員
int arr[];
};
int main()
{
//此結構體記憶體的大小為 4
struct S s;
printf("%d\n",sizeof(s));//計算次結構體大小輸出 4 并沒有計算arr數組的大小
//給它動态配置設定4+20個位元組的記憶體 24>4
struct S* ps = (struct S*)malloc(sizeof(struct S) + 5*sizeof(int));
return 0;
}