深入了解一下C語(yǔ)言中的柔性數(shù)組
什么是柔性數(shù)組
柔性數(shù)組是在C99中定義的
結(jié)構(gòu)體的最后一個(gè)元素允許是未知大小的數(shù)組,這就叫柔性數(shù)組
柔性數(shù)組的長(zhǎng)度可以寫(xiě)成0,也可以不規(guī)定數(shù)組長(zhǎng)度
下面兩種寫(xiě)法都是正確的
struct S
{
int i;
int a[0];//柔性數(shù)組成員
}
struct S
{
int i;
int a[];//柔性數(shù)組成員
}
- 結(jié)構(gòu)體中的柔性數(shù)組成員前面至少有一個(gè)其他成員
- sizeof返回的這種結(jié)構(gòu)體的大小不包括柔性數(shù)組的大小
- 包含柔性數(shù)組成員的結(jié)構(gòu)體用malloc ()函數(shù)進(jìn)行內(nèi)存的動(dòng)態(tài)分配,并且分配的內(nèi)存應(yīng)該大于結(jié)構(gòu)的大
小,以適應(yīng)柔性數(shù)組的預(yù)期大小。
柔性數(shù)組的使用
typedef struct S
{
int i;
char c[];//c是柔性數(shù)組
}S;
int main()
{
S* p = (S*)malloc(sizeof(S) + 10 * sizeof(char));
if (p == NULL)
{
perror("malloc");
return 1;
}
p->i = 10;
for (int i = 0; i < 10; i++)
{
p->c[i] = 'a';
}
free(p);
p = NULL;
return 0;
}
在malloc開(kāi)辟空間時(shí),開(kāi)辟空間大小為sizeof(S) + 10 * sizeof(char),前面的sizeof(S)其實(shí)是表示結(jié)構(gòu)體中int i的大小,后面則是給c開(kāi)辟了10個(gè)字節(jié)大小的連續(xù)空間
如果覺(jué)得前面開(kāi)辟空間小了,數(shù)組c不夠長(zhǎng),還可以用realloc函數(shù)對(duì)內(nèi)存大小進(jìn)行調(diào)整
int main()
{
S* p = (S*)malloc(sizeof(S) + 10 * sizeof(char));
if (p == NULL)
{
perror("malloc");
return 1;
}
p->i = 10;
S* ptr = (S*)realloc(p, sizeof(S) + 20 * sizeof(char));
if (ptr == NULL)
{
perror("realloc");
return 1;
}
p = ptr;
for (int i = 0; i < 20; i++)
{
p->c[i] = 'a';
}
free(p);
p = NULL;
return 0;
}
其實(shí)我們也可以寫(xiě)出另一種形式的結(jié)構(gòu)體,它的功能與柔性數(shù)組類似
typedef struct S2
{
it i;
char* c;
}S2;
對(duì)于這個(gè)結(jié)構(gòu)體的使用如下:
int main()
{
S2* p = (S2*)malloc(sizeof(S2));
p->i = 10;
p->c = (char*)malloc(10 * sizeof(char));
for (int i = 0; i < 10; i++)
{
p->c[i] = 'a';
}
free(p->c);
p->c = NULL;
free(p);
p = NULL;
return 0;
}
為了使用這個(gè)結(jié)構(gòu)體,需要先給結(jié)構(gòu)體開(kāi)辟一個(gè)空間S2* p = (S2*)malloc(sizeof(S2));然后再需要?jiǎng)討B(tài)開(kāi)辟一個(gè)塊空間讓c指向
這種寫(xiě)法需要開(kāi)辟2次內(nèi)存,同樣在最后釋放內(nèi)存是,也需要free2次
所以就可以看出柔性數(shù)組的好處:
第 一個(gè)是方便內(nèi)存釋放
因?yàn)椴徽撌俏覀冊(cè)谑褂脮r(shí)或給別人寫(xiě)一個(gè)函數(shù)讓別人使用時(shí),如果在里面做了二次內(nèi)存分配,可能別人使用時(shí)并不會(huì)知道結(jié)構(gòu)體內(nèi)部還有一個(gè)成員需要釋放。所以就需要把內(nèi)存一次性分配好,在最后釋放一次內(nèi)存就可以了
第二個(gè)是加快訪問(wèn)
如果二次內(nèi)存分配,就會(huì)在內(nèi)存中產(chǎn)生一些內(nèi)存碎片,這樣即浪費(fèi)了空間也不利于訪問(wèn)
到此這篇關(guān)于深入了解一下C語(yǔ)言中的柔性數(shù)組的文章就介紹到這了,更多相關(guān)C語(yǔ)言柔性數(shù)組內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)簡(jiǎn)單的ls命令及其原理
這篇文章主要介紹了C++實(shí)現(xiàn)簡(jiǎn)單的ls命令及其原理,C++實(shí)現(xiàn)ls命令可通過(guò)調(diào)用系統(tǒng)函數(shù)實(shí)現(xiàn)讀取目錄中的文件名和屬性,再通過(guò)標(biāo)準(zhǔn)輸出進(jìn)行顯示,需要的朋友可以參考下2023-05-05
C++中memcpy函數(shù)的使用以及模擬實(shí)現(xiàn)
memcpy是c和c++使用的內(nèi)存拷貝函數(shù),本文主要介紹了C++中memcpy函數(shù)的使用以及模擬實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
C語(yǔ)言實(shí)現(xiàn)掃雷OvO(完整代碼)
相信大家都玩過(guò)掃雷游戲,因?yàn)樗?jīng)典了,今天我們用C語(yǔ)言來(lái)模擬實(shí)現(xiàn)掃雷游戲,結(jié)合示例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2022-04-04
C++利用Socket實(shí)現(xiàn)主機(jī)間的UDP/TCP通信
這篇文章主要為大家詳細(xì)介紹了C++如何利用Socket實(shí)現(xiàn)主機(jī)間的UDP/TCP通信功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2023-01-01
C/C++實(shí)現(xiàn)手寫(xiě)數(shù)字識(shí)別的示例詳解
這篇文章主要為大家詳細(xì)介紹了如何使用C/C++實(shí)現(xiàn)手寫(xiě)數(shù)字識(shí)別,分別處理 32*32 文本數(shù)據(jù)集和mnist 28*28 png數(shù)據(jù)集,感興趣的小伙伴可以跟隨小編一起了解一下2023-10-10

