前言:
? ? ? ? 由于這塊內容所謂綜合性比較高,有數組的知識,有結構體的知識,還有動態內存管理的知識,所以我就單獨寫一篇博客,此謂番外篇。
柔性數組的概念
? ? ? ? 定義在結構體的最后一個元素的位置且大小未知的數組就叫柔性數組。
#include<stdio.h>
#include<stdlib.h>
struct test1
{int n;int arr[];//柔性數組
};struct test2
{int n;int arr[0];//柔性數組
};int main()
{return 0;
}
? ? ? ? 以上這兩種定義的方式都是柔性數組,但可能有的編譯器上并不是兩種情況都支持。
柔性數組的特點
? ? ? ? 1.柔性數組的成員前邊必須要有別的成員。
? ? ? ? 2.sizeof返回這種結構體的大小不會包括柔性數組的內存
? ? ? ? 3.必須要和動態內存分配(malloc函數等)一起結合使用。并且在動態分配內存大小的時候給柔性數組預留大小。
柔性數組的使用
? ? ? ? 如果有結構體或者動態內存管理等相關知識不知道的,可以去看一下我寫的博客,鏈接如下。
????????C語言---自定義類型(上)(結構體類型)-CSDN博客
????????C語言---動態內存管理-CSDN博客
????????大家簡單看一下我下邊的代碼(代碼1)示例就懂柔性數組的基本使用了。
#include<stdio.h>
#include<stdlib.h>
struct test
{int n;int arr[];
};int main()
{//動態申請空間//前邊半部分是給除去柔性數組的其他成員在堆區分配空間,后半部分申請的空間就給到的是結構體struct test* pt = (struct test*)malloc(sizeof(struct test) + 5 * sizeof(int));if (pt == NULL){//進入表示開辟空間失敗perror("malloc");return 1;}//使用pt->n = 10;for (int i = 0; i < 5; i++){pt->arr[i] = i + 1;}//空間不夠擴容struct test* ptr = (struct test*)realloc(pt, sizeof(struct test) + 10 * sizeof(int));if (ptr == NULL){perror("realloc");return 1;}pt = ptr;ptr = NULL;//釋放空間free(pt);pt = NULL;return 0;
}
? ? ? ? 下邊來看看內存里邊大概是什么樣子的
柔性數組的優勢
? ? ? ? 先來看一下下邊的代碼(代碼2),可以產生與剛才的柔性數組一樣的效果。
#include<stdio.h>
struct test2
{int n;int* arr;//arr指針可以指向一塊空間
};int main()
{//申請空間//給結構體整體分配空間struct test2* pt = (struct test2*)malloc(sizeof(struct test2));if (pt == NULL){perror("malloc1");return 1;}//使用pt->n = 10;//另外開辟一塊空間讓arr指針指向它pt->arr = (int*)malloc(5 * sizeof(int));if (pt->arr == NULL){perror("malloc2");return 1;}//使用arr指向的空間for (int i = 0; i < 5; i++){pt->arr[i] = i + 1;}//空間不夠擴容int* ptr = (int*)realloc(pt->arr, 10 * sizeof(int));if (ptr == NULL){perror("realloc");return 1;}pt->arr = ptr;ptr = NULL;//使用................//釋放//兩次釋放,先釋放arr指向的空間,再釋放結構體的空間free(pt->arr);pt->arr = NULL;free(pt);pt = NULL;return 0;
}
? ? ? ? 代碼2的內存結構大致如下圖
? ? ? ? 代碼1和代碼2有相同的效果,但很明顯用代碼1會更加好一點,也就是用柔性數組會更好一些,它的優勢就是減少了內存碎片,提高訪問速度,內存碎片就是指的每次動態內存申請的時候每一塊空間之間的被浪費的間隙空間(不理解也沒事),用柔性數組最大的好處就是方便內存釋放,只需要free一次。