開發(fā)常使用方式之“柔性數(shù)組”
掃描二維碼
隨時(shí)隨地手機(jī)看文章
前言
在軟件開發(fā)過程中,常遇到一些不定長的數(shù)據(jù)處理和數(shù)據(jù)傳輸?shù)葓?chǎng)景,最開始的做法大多是定義一個(gè)結(jié)構(gòu)體,包含數(shù)據(jù)長度和數(shù)據(jù)地址,如:
struct Frame { int type; int length; char *pBuf; };
這種寫法對(duì)于數(shù)據(jù)同步處理基本沒什么問題,若是數(shù)據(jù)異步處理時(shí)則在使用上會(huì)稍微復(fù)雜一些。
異步處理數(shù)據(jù)時(shí)要考慮變量和內(nèi)存的生命周期,否則容易出現(xiàn)內(nèi)存泄漏的問題,因?yàn)樯婕暗絻?nèi)存管理的問題。
概念
數(shù)組長度為0,也叫柔性數(shù)組,其主要用途是為了滿足需要變長度的結(jié)構(gòu)體,本質(zhì)是為了方便內(nèi)存緩沖區(qū)的管理。
在標(biāo)準(zhǔn)C和C++中,長度為0的數(shù)組是被禁止使用的。不過在GNU C中,存在一個(gè)非常奇怪的用法,那就是長度為0的數(shù)組,比如Array[0]
使用
柔性數(shù)組的最典型的用法就是數(shù)組位于結(jié)構(gòu)體中的最后一項(xiàng)。
struct Frame { int type; int length; char buf[0]; };
如果你將上面的長度為0的數(shù)組換為指針,那么在分配內(nèi)存時(shí),需采用兩步:首先,需為結(jié)構(gòu)體分配一塊內(nèi)存空間;其次再為結(jié)構(gòu)體中的成員變量分配內(nèi)存空間。這樣兩次分配的內(nèi)存是不連續(xù)的,需要分別對(duì)其進(jìn)行管理。當(dāng)然也能為分配連續(xù)的內(nèi)存,但是還是需要重新將指針重新指向。
struct Frame { int type; int length; char *pBuf; }; /* 第一種:分配兩次內(nèi)存,內(nèi)存通常不連續(xù) */ struct Frame *ptFrame; ptFrame = (struct Frame *)malloc(sizeof(struct Frame)); ptFrame->pBuf = (char *)malloc(ptFrame->length); printf("show: %s", ptFrame->pBuf); free(ptFrame->pBuf); free(ptFrame); ptFrame = NULL; /* 第二種:分配一次內(nèi)存,內(nèi)存連續(xù) */ char *pBuf; struct Frame *ptFrame; // 臨時(shí)用一個(gè)char類型指針去管理分配內(nèi)存,之后可以通過struct Frame指針管理即可 pBuf = (char *)malloc(sizeof(struct Frame) + ptFrame->length); ptFrame = (struct Frame *)&pBuf[0]; ptFrame->pBuf = (char *)&pBuf[sizeof(struct Frame)]; printf("show: %s", ptFrame->pBuf); free(ptFrame); // 也可以使用 free(pBuf); ptFrame = NULL;
當(dāng)使用長度為0的數(shù)組時(shí),則是采用一次分配的原則,一次性將所需的內(nèi)存全部分配給它。相反,釋放時(shí)也是一樣的。并且使用起來也十分方便,完全按照數(shù)組的方式進(jìn)行訪問即可。
/* 連續(xù)分配兩次內(nèi)存,內(nèi)存通常不連續(xù) */ struct Frame { int type; int length; char buf[0]; }; struct Frame *ptFrame; ptFrame = (struct Frame *)malloc(sizeof(struct Frame) + ptFrame->length); printf("show: %s", ptFrame->buf); free(ptFrame); ptFrame = NULL;
相對(duì)于上面用指針的方式,使用長度為0的數(shù)組更加方便內(nèi)存緩沖區(qū)的管理;除此之外,長度為0的數(shù)組并不占有內(nèi)存空間,而指針方式需要占用內(nèi)存空間。
對(duì)于編譯器而言, 數(shù)組名僅僅是一個(gè)符號(hào), 它不會(huì)占用任何空間, 它在結(jié)構(gòu)體中, 只是代表了一個(gè)偏移量, 代表一個(gè)不可修改的地址常量!
總結(jié)
綜上,對(duì)于長度為0的數(shù)組具備以下優(yōu)勢(shì):
-
方便內(nèi)存的管理
-
長度為0的數(shù)組并不占有內(nèi)存空間,而指針方式需要占用內(nèi)存空間。
-
對(duì)于長度為0的數(shù)組的訪問可采用數(shù)組方式進(jìn)行
當(dāng)然,最開始的提到了“在標(biāo)準(zhǔn)C和C++中,長度為0的數(shù)組是被禁止使用的”,雖然可以啟用“GNU C”進(jìn)行編譯,但是不一定所有編譯器都支持“GNU C”,因此,我們可以在此基礎(chǔ)上進(jìn)行變型,合理利用標(biāo)準(zhǔn)C和C++中的數(shù)組長度定義規(guī)則,完成該方式的實(shí)現(xiàn)。
那么你知道如何合理利用規(guī)則達(dá)到標(biāo)準(zhǔn)C和C++的要求實(shí)現(xiàn)柔性數(shù)組嗎?變型后的柔性數(shù)組相對(duì)于變型前的柔性數(shù)組有什么缺點(diǎn)嗎?感興趣的朋友可以在評(píng)論區(qū)進(jìn)行留言…





