<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
記憶體的簡答來說的三大操作:分配----使用----釋放
記憶體管理指的是:分配— ----釋放
我們編寫的程式程式碼:使用
程式本質上就是處理資料,資料資訊需要存放在記憶體裡,就是用二極體表示的開斷表示二進位制數,進一步用二進位制數表示萬物:如音樂、文字、視訊、圖片、等等各種資源。
分配–釋放:為了更好的利用和回收記憶體資源,最大程度的發揮計算資源,統一作業系統來排程
動態記憶體分配其實就要談到自動記憶體分配
自動分配:記憶體其實就是我們在程式設計檔案裡定義的變數實際在執行時對映的記憶體,這部分變數的記憶體都是由系統自動管理(分配-釋放)。函數體(或者語句塊)內的變數都是分佈在函數 幀 裡面,執行時就會把這個幀插入到函數執行棧裡,記憶體這些都由系統分撥,執行完就出棧,記憶體也被作業系統回收,一致到主函數出棧,程式退出。
動態分配:就是我們自己手動申請作業系統給我們程式分配的記憶體,記憶體區域主要在於 堆 上,這部分資源是我們手動申請和回收的。分配到的資源是我們來操作、存放資料的地方。
實際上我們定義的變數最後也會被翻譯為地址,都是通過定址來操作變數的值(可以去看看組合語言)
#include <stdio.h> #include <stdlib.h> int main(void) { int*pi=(int*)malloc(sizeof(int)); *pi=5; printf("*pi:%dn",*pi); free(pi); return 0; }
注意點
int *pi=(int)malloc((4));
有幾個記憶體分配函數可以用來管理動態記憶體,雖然具體可用的函數取決於系統,但大部分系統的stdlib.h標頭檔案中都有如下函數:
malloc()
realloc()
calloc()
函數 | 描述 |
---|---|
malloc | 從堆上分配記憶體 |
realloc | 在之前分配的記憶體塊的基礎上,將記憶體重新分配為更大或者更小的部分 |
calloc | 從堆上分配記憶體並清零 |
malloc函數從堆上分配一塊記憶體,所分配的位元組數由該函數唯一的引數指定,返回值是void指標,如果記憶體不足,就會返回NULL。此函數不會清空或者修改記憶體。
宣告:void* malloc(size_t);
範例用法:int* pi=(int*)malloc(sizeof(int));
因為當malloc無法分配記憶體時會返回NULL,在使用它返回的指標之前先檢查NULL是不錯的做法,如下所示:
int*pi=(int*)malloc(sizeof(int)); if(pi!=NULL) { //指標沒有問題 }else { //無效的指標 }
初始化靜態或全域性變數時不能呼叫函數。下面的程式碼宣告一個靜態變數,並試圖用malloc來初始化:
*static int pi = malloc(sizeof(int));
這樣會產生一個編譯時錯誤訊息,全域性變數也一樣。
對於靜態變數,可以通過在後面用一個單獨的語句給變數分配記憶體來避免這個問題。但是全域性變數不能用單獨的賦值語句,因為全域性變數是在函數和可執行程式碼外部宣告的,賦值語句這類程式碼必須出現在函數中:
static int *pi;
pi = malloc(sizeof(int));
宣告:void *realloc(void *ptr,size t size);
realloc函數返回指向記憶體塊的指標。該函數接受兩個引數,第一個引數是指向原記憶體塊的指標,第二個是請求的大小。重新分配的塊大小和第一個引數參照的塊大小不同。返回值是指向重新分配的記憶體的指標。
第一個引數 | 第二個引數 | 行為 |
---|---|---|
空 | 無 | 同malloc |
非空 | 0 | 原記憶體塊被釋放 |
非空 | 比原記憶體塊小 | 利用當前的塊分配更小的塊 |
非空 | 比原記憶體塊大 | 要麼在當前位置要麼在其他位置分配更大的塊 |
堆管理器可以重用原始的記憶體塊,且不會修改其內容。不過程式繼續使用的記憶體超過了所請求的8位元組。也就是說,我們沒有修改字串以便它能裝進8位元組的記憶體塊中。在本例中,我們本應該調整字串的長度以使它能裝進重新分配的8位元組。實現這一點最簡單的辦法是將NUL賦給地址507。實際使用的記憶體超出分配的記憶體不是個好做法,應該避免。
calloc函數在申請記憶體時會清空記憶體【清空記憶體的意思是將其內容置為二進位制0】
宣告: void *calloc(size_t numElements,size_t elementSize);
calloc函數會根據numElements和elementSize兩個引數的乘積來分配記憶體,並返回一個指向記憶體的第一個位元組的指標。如果不能分配記憶體,則會返回NULL。此函數最初用來輔助分配陣列記憶體。
如果numElements或elementSize為0,那麼calloc可能返回空指標。如果calloc無法分配記憶體就會返回空指標,而且全域性變數errno會設定為ENOMEM(記憶體不足),這是POSIX錯誤碼,有的系統上可能沒有。
有了動態記憶體分配,程式設計師可以將不再使用的記憶體返還給系統,這樣可以釋放記憶體
留作他用。通常用free函數實現這一點,該函數的原型如下:
宣告: void free(void *ptr);
指標引數應該指向由malloc類函數分配的記憶體的地址,這塊記憶體會被返還給堆。儘管指標仍然指向這塊區域,但是我們應該將它看成指向垃圾資料。稍後可能重新分配這塊區域,並將其裝進不同的資料。
要點
如果記憶體已經釋放,而指標還在參照原始記憶體,這樣的指標就稱為迷途指標。迷途指標沒有指向有效物件,有時候也稱為過早釋放。
迷途指標帶來的問題:
造成的原因:
//第一種情況 int*pi = (int*)malloc(sizeof(int)); printf("*pi:%dn",*pi); free(pi); *pi = 10; //第二種情況 int*p1 = (int*)malloc(sizeof(int)); *p1 = 5; int* p2; p2 = p1; free(p1); *p2 = 10;//迷途指標 //第三種情況 /* 大部分編譯器都把塊語句當做一個棧幀。tmp變數分配在棧幀上,之後在塊語句退出時會出棧。 pi指標現在指向一塊最終可能被其他活躍記錄(比如foo函數)覆蓋的記憶體區域。 圖2-13說明的就是這種情形。 */ int *pi; int tmp = 5; pi = &tmp; //這裡pi變成了迷途指標 foo();
本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注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