本文主要講解柔性數組的相關知識點,并穿插一下C/C++程序的內存開辟,涉及到動態內存管理函數,如有不了解的,請參考這一篇文章【C語言】小王帶您輕松實現動態內存管理(簡單易懂)_小王學代碼的博客-博客
創新互聯主營環江網站建設的網絡公司,主營網站建設方案,成都app軟件開發,環江h5重慶小程序開發搭建,環江網站營銷推廣歡迎環江等地區企業咨詢
目錄
前言
一、C/C++程序的內存開辟
1.1 初步分析內存
1.2 詳細分析內存管理
二、柔性數組
2.1 柔性數組的特點
2.2 柔性數組的使用
2.3 柔性數組的優勢
總結
首先,我們知道在程序編譯、運行的過程中,程序中的變量等會再內存中申請空間,這個時候呢,就需要我們來了解一下,C/C++程序的內存開辟是什么情況。
其次,我們都知道數組,知道數組是在編譯的時候,就已經固定了內存空間,元素大小,那么什么又叫做柔性數組呢,是不是我們所想的那樣,可以任意變化數組大小呢?
接下來,讓小王帶領大家一一探討!!!
我們一定想知道,到底C/C++程序在運行過程會將內存分為幾部分,是如何劃分的?
首先有一個簡易圖,讓我們大致了解一下,變量放在哪,動態管理函數又放在哪?
內存空間可以初步分為:棧區、堆區、靜態區
如圖所示:
1.1 初步分析內存棧區:主要是局部變量和函數形參在這個地方占用空間
堆區:動態內存管理函數malloc、free、calloc、realloc等等函數申請空間
靜態區:存放全局變量、靜態變量?
有關于堆區的這些函數可以去上一篇函數去看看,靜態區也沒什么好講的,主要是全局變量和靜態變量。
全局變量:在整個程序中所有函數之內都可以使用,可以更改內容,只在程序結束時退出
靜態變量:由static修飾的變量,可以更改內容,在程序結束的時候才會失去對空間的使用權
棧區,由一個常見的小問題,返回棧區空間問題
如圖所示:
1.2 詳細分析內存管理我們將內存更加細致的分為,內核空間、棧、內存映射段、堆、數據段、代碼段
如圖所示:
C/C++程序內存分配的幾個區域:
1. 棧區(stack):在執行函數時,函數內局部變量的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元自動被釋放。棧內存分配運算內置于處理器的指令集中,效率很高,但是分配的內存容量有限。 棧區主要存放運行函數而分配的局部變量、函數參數、返回數據、返回地址等。
2. 堆區(heap):一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收 。分配方式類似于鏈表。
3. 數據段(靜態區)(static)存放全局變量、靜態數據。程序結束后由系統釋放。
4. 代碼段:存放函數體(類成員函數和全局函數)的二進制代碼
有了上圖,我們就可以更加清晰的認知到,由static來靜態修飾局部變量的意義了,相當于改變了生命周期。
二、柔性數組實際上普通的局部變量是在棧區分配空間的,棧區的特點是在上面創建的變量出了作用域就銷毀。
但是被static修飾的變量存放在數據段(靜態區),數據段的特點是在上面創建的變量,直到程序結束才銷毀
所以生命周期變長。
柔性數組,是C99標準中,結構中的最后一個元素允許是未知大小的數組,這就是柔性數組成員
例如:
typedef struct Node {
int i;
int arr[];//這就是柔性數組成員
//或者是這樣的情況:int arr[0]
//int arr[0] 中的零并沒有實際意義,并不是說明0個元素,這只是柔性數組的標識
};
2.1 柔性數組的特點1.結構中的柔性數組成員前面必須至少一個其他成員。? ? ? ??
2.sizeof 返回的這種結構大小不包括柔性數組的內存。
3.包含柔性數組成員的結構用malloc ()函數進行內存的動態分配,并且分配的內存應該大于? 結構的大小,以適應柔性數組的預期大小
圖示解釋:
2.2 柔性數組的使用實際上柔性數組的使用和其他數組的使用是沒有什么區別的,只是說,柔性數組是一種方式,可以在不知道需要多大的數組元素個數的時候,使用, 這樣在后面可以根據自己所需,申請適當空間大小的數組來使用。所以是柔性的,普通數組是固定死的
代碼演示:
typedef struct Node {
int i;
int arr[];//這就是柔性數組成員
//或者是這樣的情況:int arr[0]
//int arr[0] 中的零并沒有實際意義,并不是說明0個元素,這只是柔性數組的標識
}Node;
int main()
{
int sz = sizeof(Node);
printf("%d\n", sz);//4 只算除了柔性數組的其他成員的內容
Node* p = (Node*)malloc(sizeof(Node)+10*sizeof(int));
//創建 p結構體的空間,sizeof(Node)為int i 的空間 10*sizeof(int) 是留給柔性數組的空間
for (int i = 0; i< 10; i++) {
p->arr[i] = i + 1;
}
for (int i = 0; i< 10; i++) {
printf("%d ", p->arr[i]);
}
free(p);
return 0;
}
根據自己所需,我們設計了10個int類型元素的數組arr
2.3 柔性數組的優勢我們現在可能反應回來了,可能有人在問,這個柔性數組,我們也可以這樣搞呀!
代碼演示:
struct S {
int n;
int* arr;
};
int main()
{
//先申請結構體的空間
struct S* s = (struct S*)malloc(sizeof(struct S));
//賦值
s->n = 10;
//再申請int*的空間
s->arr = (int*)malloc(sizeof(int) * 10);
//這樣申請到了10個整型大小的空間
for (int i = -0; i< 10; i++) {
s->arr[i] = i + 1;
}
for (int i = 0; i< 10; i++) {
printf("%d ", s->arr[i]);
}
free(s->arr);//先取消s.arr的空間并置為NULL,如果先s置為NULL,再滯空arr 的時候會警告
s->arr = NULL;
free(s);//要注意先后順序,先內部的arr free滯空,再s free滯空
s = NULL;
return 0;//防止錯誤吧,邏輯問題
}
我們能看到,這樣的代碼也能實現柔性數組那樣的功能啊,確實是可以實現的,但是我們來分析一下,使用柔性數組有什么優勢呢?
第一:方便內存釋放
如果我們的代碼是在一個給別人用的函數中,你在里面做了二次內存分配,并把整個結構體返回給用戶。用戶調用free可以釋放結構體,但是用戶并不知道這個結構體內的成員也需要free,所以你不能指望用戶來發現這個事。所以,如果我們把結構體的內存以及其成員要的內存一次性分配好了,并返回給用戶一個結構體指針,用戶做一次free就可以把所有的內存也給釋放掉。
第二:這樣有益于訪問速度
連續的內存有益于提高訪問速度,也有益于減少內存碎片。(其實,我個人覺得也沒多高了,反正你跑不了要用做偏移量的加法來尋址)
就是說使用柔性數組,只需要malloc一次、free一次、且空間是連續的
非柔性數組,需要malloc兩次、free一次、且空間不是連續的
這里我們就知道了,C/C++程序的內存分配是什么情況,簡易的內存分配可以怎么描述?更加細致的分配,我也在本文中講解了,最后是對于柔性數組的分析和使用,可能有些小伙伴覺得,哎,好像這個柔性數組沒有什么太大的用處啊,我可以用別的方法實現呀(有講),實際上這是C語言給我們提供的一種解決問題的思路或者是方式,不需要深究,我們知道,會用即可!!!
那么本文就到此結束了,下一篇文章,我們來講述一下,文件操作是如何使用的,相關函數又是如何,可以對通訊錄做升級處理啦!!!
你是否還在尋找穩定的海外服務器提供商?創新互聯www.cdcxhl.cn海外機房具備T級流量清洗系統配攻擊溯源,準確流量調度確保服務器高可用性,企業級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧
新聞標題:【C語言】柔性的數組是什么?C/C++程序的內存開辟又是?-創新互聯
標題來源:http://vcdvsql.cn/article8/phsip.html
成都網站建設公司_創新互聯,為您提供外貿建站、網站內鏈、移動網站建設、微信公眾號、品牌網站建設、面包屑導航
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯