C語言學習
柔性數組
友情鏈接:C語言專欄
文章目錄
- C語言學習
- 前言:
- 柔性數組
- 一、柔性數組的特點
- 二、柔性數組的使用
- 三、柔性數組的優勢
- 總結
- 附錄
- 上文鏈接
- 專欄
前言:
在有結構體和動態內存分配的知識后,今天咱們來說說柔性數組吧!!!
柔性數組
C99 中,結構中的最后?個元素允許是未知大小的數組,這就叫做柔性數組成員。
例如:
struct S
{int i;int a[0];//柔性數組成員
};
有些編譯器會報錯?法編譯可以改成:
struct S
{int i;int a[];//柔性數組成員
};
一、柔性數組的特點
- 結構中的柔性數組成員前面必須至少一個其他成員。
- sizeof 返回的這種結構大小不包括柔性數組的內存。
- 包含柔性數組成員的結構用malloc ()函數進行內存的動態分配,并且分配的內存應該大于結構的大小,以適應柔性數組的預期大小。
示例:
struct S
{int i;int a[];//柔性數組成員
};
int main()
{printf("%d\n", sizeof(struct S));//輸出的是4return 0;
}
輸出:
二、柔性數組的使用
//代碼1
#include<stdio.h>
#include<stdlib.h>
struct S
{int i;int a[];//柔性數組成員
};
int main()
{struct S* ps = (struct S*)malloc(sizeof(struct S) + 5 * sizeof(int));//動態開辟內存:4+20個字節//4個字節為i,20個字節為數組if (ps == NULL)//判斷是否開辟成功{perror("malloc failed");exit(EXIT_FAILURE); }//使用:ps->i = 100;for (int i = 0; i < 5; i++){ps->a[i] = i;}//增加空間reallocstruct S* tmp = (struct S*)realloc(ps, sizeof(struct S) + 10 * sizeof(int)); //給數組增加20個字節(5個元素)if (tmp == NULL)//判斷是否開辟成功{perror("malloc failed");exit(EXIT_FAILURE);}ps = tmp;//繼續由ps管理這塊內存;tmp = NULL;//使用//……//釋放free(ps);ps = NULL;return 0;
}
三、柔性數組的優勢
上述的結構也可以設計為別的結構,也能完成同樣的效果。
//代碼2
#include<stdio.h>
#include<stdlib.h>
struct S
{int i;int* a;//通過指針指向一塊空間,實現與柔性數組相同的效果
};
int main()
{struct S* ps = (struct S*)malloc(sizeof(struct S));//動態開辟內存一個struct S大小的空間if (ps == NULL)//判斷是否開辟成功{perror("malloc failed");exit(EXIT_FAILURE);}ps->i = 100;ps->a = (int*)malloc(5 * sizeof(int)); //動態開辟內存5個int大小的空間,并將起始地址給aif (ps->a == NULL)//判斷是否開辟成功{perror("malloc failed");exit(EXIT_FAILURE);}//使用for (int i = 0; i < 5; i++){ps->a[i] = i;}//增加空間reallocint* tmp = (int*)realloc(ps->a, sizeof(10 * sizeof(int)));//給ps->a指向的空間增加20個字節(5個元素)if (tmp == NULL)//判斷是否開辟成功{perror("malloc failed");exit(EXIT_FAILURE);}ps->a = tmp;tmp = NULL;//使用//……//釋放//注意先后順序free(ps->a );ps->a = NULL;free(ps);ps = NULL;return 0;
}
上述代碼1和代碼2可以完成同樣的功能,但是代碼1的實現有兩個好處:
第一個好處是:方便內存釋放
咱們上面發現,代碼2我們會釋放兩次內存。有如果我們的代碼是在?個給別?用的函數中,你在里面做了二次內存分配,并把整個結構體返回給用戶。用戶調用free可以釋放結構體,但是用戶并不知道這個結構體內的成員也需要free,所以你不能指望用戶來發現這個事。所以,如果我們把結構體的內存以及其成員要的內存?次性分配好了,并返回給用戶?個結構體指針,用戶做?次free就可以把所有的內存也給釋放掉。
第二個好處是:這樣有利于訪問速度
連續的內存有益于提高訪問速度,也有益于減少內存碎片。圖示:
總結
柔性數組是C99標準引入的重要特性,它允許在結構體的末尾定義一個長度可變的數組。通過結合動態內存管理,柔性數組能夠高效地處理不確定大小的數據集合,是C程序員進階必備技能之一。
附錄
上文鏈接
《動態內存分配避坑指南:六大易錯點解析與經典筆試題實戰》
專欄
C語言專欄