在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<abbr id="27omo"></abbr>

<menu id="27omo"><dl id="27omo"></dl></menu>
    • <label id="27omo"><tt id="27omo"></tt></label>

      博客專欄

      EEPW首頁 > 博客 > C語言柔性數(shù)組詳解

      C語言柔性數(shù)組詳解

      發(fā)布人:電子禪石 時間:2023-02-19 來源:工程師 發(fā)布文章
      一、柔性數(shù)組是什么?

      C99中,結(jié)構(gòu)體中的最后一個元素允許是未知大小的數(shù)組,這就叫作柔性數(shù)組,for example:

       struct st_type{
      	int i;
      	int a[0];//柔性數(shù)組成員,也可以寫int a[];};

      結(jié)構(gòu)體成員a數(shù)組,它的數(shù)組大小是沒有確定的,將來如果需要可以大也可以小。
      有些編譯器支持a[0]這種寫法,有些編譯器支持a[ ]這種寫法,具體取決編譯器。


      二、柔性數(shù)組的特點

      1.結(jié)構(gòu)體中柔性數(shù)組成員前面必須至少有一個其他成員

      示例如下:


       struct st_type

      {

      int i;

      int a[0];//柔性數(shù)組成員,也可以寫int a[];

      };


      比如上面這段代碼,如果你要創(chuàng)建一個柔性數(shù)組a,前面必須創(chuàng)建一些別的成員

      ————————————————

      2.sizeof返回的這種結(jié)構(gòu)大小不包括柔性數(shù)組的內(nèi)存

       struct st_type
      {
      	int i;//4字節(jié)
      	int a[0];//柔性數(shù)組成員,也可以寫int a[];
      	//因為是柔性數(shù)組,無法確認a占幾個字節(jié)
      };
       int main()
       {
      	 printf("%d\n", sizeof(struct st_type));//打印4
      	 return 0;
       }

      這里計算包含柔性數(shù)組的結(jié)構(gòu)體大小,因為柔性數(shù)組本身是無法確定有幾個字節(jié)的,所以計算整體結(jié)構(gòu)體大小時,會省略柔性數(shù)組的計算。


      3.包含柔性數(shù)組成員的結(jié)構(gòu)用malloc()函數(shù)進行內(nèi)存的動態(tài)分配,并且分配的內(nèi)存應該大于結(jié)構(gòu)的大小,以適應柔性數(shù)組的預期大小

      ps:除了malloc函數(shù),realloc、calloc等動態(tài)內(nèi)存開辟的函數(shù)也需要類似的操作


      比如說我現(xiàn)在要數(shù)組a里面有10個元素,現(xiàn)在進行malloc一下

      ————————————————

      示例如下:

      #include<string.h>
      #include<errno.h>
      struct st_type
      {
      	int i;//4字節(jié)
      	int a[0];//柔性數(shù)組成員,也可以寫int a[];
      };
      int main()
      {
          //假設我現(xiàn)在需要a里有10個元素
      	struct st_type*ps=(struct st_type*)malloc(sizeof(struct st_type) + 10 * sizeof(int));
      	if (ps == NULL)//由于空間可能不夠開辟導致malloc開辟失敗,開辟失敗會返回空指針
      	{
      		printf("%s\n", strerror(errno));
      		return -1;//程序出問題后,跳出程序
      	}
      	//開辟成功
      	int j = 0;
      	for (j = 0;j < 10;j++)
      	{
      		ps->a[j] = j;
      	}
      	for (j = 0;j < 10;j++)
      	{
      		printf("%d ", ps->a[j]);//打印0-9
      	}
      	printf("\n");
      	//如果想繼續(xù)用柔性數(shù)組a進行打印
      	//比如現(xiàn)在a里只有10個元素,我用完10個了,我還要繼續(xù)來10個,用realloc追加
      	struct st_type*ptr=realloc(ps, sizeof(struct st_type) + 20 * sizeof(int));//ps:realloc第二個參數(shù)是調(diào)整后的整體大小
      	if (ptr == NULL)
      	{
      		printf("擴容失敗\n");
      		return -1;
      	}
      	else
      	{
      		ps = ptr;
      	}
      	//擴容成功
      	int k = 0;
      	for (k = 10;k < 20;k++)
      	{
      		ps->a[k] = k;
      	}
      	for (j = 0;j < 20;j++)
      	{
      		printf("%d ", ps->a[j]);//打印0-19
      	}
      	//釋放空間
      	free(ps);
      	ps = NULL;
      	return 0;
      }

      image.png


      我們這里需要數(shù)組a里有10個元素,那我們malloc的時候要對結(jié)構(gòu)體里的整形i先開辟4個字節(jié),然后為整形數(shù)組a再開辟40個字節(jié),然后malloc函數(shù)返回開辟空間的起始地址,賦給truct st_type * 類型的ps指針。


      malloc(sizeof(struct st_type) + 10 * sizeof(int))這個操作等價于struct st_type類型創(chuàng)建一個變量所占空間,只不過是用malloc來開辟


      你改變數(shù)組a大小,追加空間時,realloc(ps, sizeof(struct st_type) + 20 * sizeof(int)),realloc的第一個參數(shù)仍然是ps,因為你當時是用malloc一次開辟出的一塊空間,你是不能單獨調(diào)整數(shù)組a的空間的

      ————————————————

      三、柔性數(shù)組的優(yōu)點

      柔性數(shù)組就是對一塊空間實現(xiàn)動態(tài)開辟嘛,那我們之前也講過指針來動態(tài)內(nèi)存開辟,我們來看一段代碼來對比一下這兩種方法:

      //用指針也可以做到a指向的空間動態(tài)變化
      struct st_type
      {
      	int i;//4字節(jié)
      	int *a;//4字節(jié),這里計算結(jié)構(gòu)體大小恰好是8字節(jié)
      };
      int main()
      {
      	struct st_type*ps = (struct st_type*)malloc(sizeof(struct st_type));
      	ps->i = 100;
      	ps->a = (int*)malloc(10 * sizeof(int));//a指向40個字節(jié)的空間,該空間由int*進行管理
      	int j = 0;
      	for (j = 0;j < 10;j++)
      	{
      		ps->a[j] = j;//a[j]=*(a+j)
      	}
      	for (j = 0;j < 10;j++)
      	{
      		printf("%d", ps->a[j]);
      	}
      	//a指向的空間不夠了,希望調(diào)整大小
      	int *ptr = (int*)realloc(ps->a, 20 * sizeof(int));
      	if (ptr == NULL)
      	{
      		printf("擴容失敗");
      		return -1;
      	}
      	else
      	{
      		ps->a = ptr;
      	}
      	//使用...
      	//釋放
      	free(ps->a);
      	ps->a = NULL;
      	free(ps);
      	ps = NULL;
      }

      這里需要注意的是,在釋放空間時,你要先釋放指針a指向的空間,然后釋放結(jié)構(gòu)體指針。


      image.png

      如上圖,我們結(jié)構(gòu)體指針ps開辟一塊空間,空間里存放整形i和整形指針a,a又malloc(后續(xù)如果需要還可以realloc追加)一塊空間,如果你先釋放掉ps,a就沒了,你就沒法找到a指向的那塊空間了。

      還是那個生動的例子 就比如a是一個警察頭子,malloc開辟的空間是臥底,只有a知道那個臥底,你現(xiàn)在警察頭子死了,再也沒法證明臥底是臥底了,也就是說a消失后,沒辦法再對開辟的空間進行釋放,這時就會造成內(nèi)存泄露,指針實現(xiàn)動態(tài)內(nèi)存調(diào)整是需要對指針釋放講解一定的順序性的

      ————————————————

      這里對比柔性數(shù)組,柔性數(shù)組和上述的指針都可以實現(xiàn)一塊空間大小的調(diào)整,但是柔性數(shù)組有兩個好處:

      第一個好處是:方便內(nèi)存釋放

      如果我們的代碼是在一個給別人用的函數(shù)中,你在里面做了二次內(nèi)存分配,并把整個結(jié)構(gòu)體返回給用戶。用戶調(diào)用free可以釋放結(jié)構(gòu)體,但是用戶并不知道這個結(jié)構(gòu)體內(nèi)的成員也需要free,所以你不能指望用戶來發(fā)現(xiàn)這個事。以上,如果我把結(jié)構(gòu)體的內(nèi)存及其成員要的內(nèi)存一次性分配好,并返回給用戶一個結(jié)構(gòu)體指針,用戶做一次free就可以把所有內(nèi)存都釋放掉,并且不用考慮前面說的釋放的順序。

      ————————————————

      第二個好處是:加快訪問速度
      連續(xù)的內(nèi)存有益于提高訪問速度,也有益于減少內(nèi)存碎片。
      ps:內(nèi)存碎片如下圖

      image.png


      總結(jié)

      本文介紹了柔性數(shù)組的定義、其三個使用特點,及其對比指針實現(xiàn)動態(tài)內(nèi)存的優(yōu)勢,并對其進行了具體舉例,知識點并不復雜,希望讀者學習完本文后能對柔性數(shù)組有更進一步的理解,祝讀者生活愉快!


      *博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。



      關(guān)鍵詞: c

      相關(guān)推薦

      技術(shù)專區(qū)

      關(guān)閉