<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
int data=20;//在棧空間上開闢4個位元組空間 char ch[5]={0};//在棧開闢5個位元組連續空間
上面展示的即為我們正常開闢固定的記憶體空間,它有兩個方面的特點
1.記憶體空間所佔大小是固定的,不能改變的。
2.建立陣列時,必須指明長度大小,在編譯時記憶體進行分配。
很顯然靜態分配記憶體分配在一些場景,就暴露出它的弊端。如果在開發之前,我們不知道空間的需求,我們有時只有在程式執行的時候才能知道自己所需要空間大小,這時候我們只能使用動態分配記憶體了。
malloc函數的引數只有一個size_t size,向記憶體申請一塊連續可用的空間,有幾點需要注意
1.如果開闢成功的話,返回指向開闢好空間的指標
2.如果開闢失敗的話,則返回NULL,因此每次開闢空間之後,都要進行檢查
3.malloc函數未定義返回型別,一切由使用者自己使用
4.需參照stdlib.h標頭檔案
free函數是和malloc配套使用的,每次在堆開闢動態空間後,程式結束之前,必須進行空間釋放,不然會出現動態空間洩露,在使用free時,仍需要注意幾點
1.如果指標指向的空間不是動態開闢的,不能用free進行釋放
2.如果指標指向的是null指標,則free函數什麼事都不做
3.free不能多次使用
4.需參照stdlib.h標頭檔案
程式碼如下(範例):
#include<stdio.h> #include<stdlib.h> #include<errno.h> #include<string.h> int main() { int* src = NULL; src = (int*)malloc(40);//開闢40位元組動態記憶體 if (src == NULL) { printf("%s", strerror(errno)); return 1; } free(src);//進行動態記憶體釋放 src = NULL; return 0; }
相信有人會問,不是已經對動態記憶體進行釋放,為什麼還要令指標等於NULL,我們偵錯一把。
這裡我們可以發現,雖然動態記憶體進行free釋放,但指標仍然指向被釋放的動態記憶體的地址,如果不置空,就會造成野指標,非法存取的問題。
calloc和malloc最大的區別就是,malloc只負責對記憶體進行動態開闢,但calloc不僅開闢,還進行初始化。
程式碼如下(範例):
#include<stdio.h> #include<stdlib.h> #include<errno.h> #include<string.h> int main() { int* src = (int*)calloc(10, sizeof(int)); if (src == NULL) { printf("%s", strerror(errno)); return 1; } free(src);//進行動態記憶體釋放 src = NULL; return 0; }
我們偵錯一把可以發現,calloc在開闢空間時同時進行了初始化。所以如何我們對申請的記憶體空間的內容要求初始化,那麼可以很方便的使用calloc函數來完成任務。
當我們一次開闢動態記憶體不夠大的時候,realloc讓動態記憶體更加的靈活。realloc幾個引數:
1.第一個引數為要調整記憶體的地址
2.調整後大小
3.調整後記憶體的起始位置
為什麼還要返回撥整後記憶體的地址,不是直接就開闢好了嗎?其實reallloc函數在開闢時有以下兩種情況:
1.原來的記憶體之後空間是足夠的,則直接開闢
2.原來的記憶體之後空間不夠用。
我們畫圖刨析一下
情況1:直接追加空間,原來資料不變
情況2:沒有足夠的空間,在堆上找一個大小合適的連續空間。所以函數返回的是一個新的記憶體地址。
程式碼如下(範例)
#include<stdio.h> #include<stdlib.h> #include<errno.h> #include<string.h> int main() { int* src = NULL; src = (int*)malloc(40);//開闢40位元組動態記憶體 if (src == NULL) { printf("%s", strerror(errno)); return 1; } src = realloc(src, 80); if (src == NULL) { printf("%s", strerror(errno)); return 1; } free(src);//進行動態記憶體釋放 src = NULL; return 0; }
1.動態記憶體越界存取
void test1() { int* src = (int*)malloc(20); if (NULL == src) { return 1; } int i = 0; for (i = 0; i < 6; i++) { (*src+i)=i } free(src); src = NULL; }
在這裡我們malloc只開闢了20個位元組,但(*src+5)造成了越界存取
void test2() { int* src = (int*)malloc(INT_MAX);//此處INT_MAX為int的最大值 *src = 10;//如果src是NULL時,無法解除參照 free(src); return 0; }
這裡未對開闢的動態記憶體空間進行是否為空的判斷,當為空時,解除參照就會出現錯誤。
void test3() { int* src = (int*)malloc(40); int i=0; for(i=0;i<6;i++) { *(src+i)=i; src++; } free(src);//此時src不指向起始位置 }
因為指標指向的地址發生變化,不在指向起始未知,進行free釋放是非常危險的。
void test4() { int a = 20; int* src = &a; free(src); }
void test5() { int* src = (int*)malloc(40); free(src); free(src);//多次釋放 }
第一個free已經將堆空間的動態記憶體進行釋放,此時src已經是一個野指標,在進行釋放是十分危險的。
void test6() { int* src = (int*)malloc(40); if (src != NULL) { } while (1); }
在開闢動態記憶體之後,一直進行while迴圈,為進行free釋放,會造成記憶體漏失。
void test(char* src) { src = (char*)malloc(30); } int main() { char* src = NULL; test(src); strcpy(src, "wo yao jin da chang"); printf(src); free(src); }
這裡會輸出wo yao jin da chang 嗎?
這裡很明顯,src仍然是NULL,所以無法輸出wo yao jin da chang
char* test() { char arr[] = "wo yao jin da chang"; return arr; } int main() { char* src = NULL; src = tset(); printf(src); return 0; }
這裡會輸出wo yao jin da chang 嗎?
這裡test函數確實把字串地址傳給了src,但是字串是區域性變數,當函數執行完之後,就銷燬了,所以src輸出的內容是隨機的。
void test() { char* src = (char*)malloc(50); if (src != NULL) { strcpy(src, "wo yao jin da chang"); } free(src); if (src != NULL) { strcpy(src, "taijuanlebujinle"); printf(src); } }
這裡會輸出taijuanlebujinle 嗎?
這裡對動態記憶體釋放後,繼續進行賦值,對野指標進行了存取是錯誤的。
看到這裡大家對動態記憶體管理已經有了一定的認識,應該特別注意這幾點,在進行動態記憶體開闢之後進行判斷是否為空,使用完後進行free釋放,並且置空,防止動態記憶體洩露,只要記住這幾點基本就可以很好的使用動態記憶體了。
以上就是深入瞭解C語言的動態記憶體管理的詳細內容,更多關於C語言動態記憶體管理的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45