Manual Memory Management

1. C語言操作

1.1 概述

C語言內存管理分statically,automatically,dynamically三種方式;static變量配置在main memory,一般在整個程序都有效;auto變量配置在stack,在包含該變量的function調用時起作用,返回時結束;對static和auto變量的大小在編譯期就需要確定。
配置內存的生命時間也會造成一些問題,static和auto不能滿足所有的情況,auto不能讓多個functions調用,同時static在程序的整個過程都存在,無論是否需要,所以我們需要更靈活的內存申請和消除。
動態內存配置可以解決上述問題,可以更靈活的管理內存,從堆-heap上申請內存;在C中使用malloc/calloc從heap上申請內存,程序通過返回的指針訪問該段內存。當此內存不再需要時,通過free消除。
malloc() can also avoid system calls by utilising fast bins
一些平臺提供開發庫,允許從 stack上配置實時動態內存,如alloca()。採取這種方式申請的內存在function結束時自動銷燬。
C的動態內存配置函數定義在stdlib.h頭文件,若需要在c++中使用請包含cstdlib.h

Function

Description

malloc

allocates the specified number of bytes

realloc

increases or decreases the size of the specified block of memory. Reallocates it if needed

calloc

allocates the specified number of bytes and initializes them to zero

free

releases the specified block of memory back to the system


1.2 比較malloc()和calloc()

1. malloc()僅接收一個參數,即配置內存的字節數量;calloc()需要兩個參數,即配置內存的變量單位數量,和變量單位的字節大小。
2. malloc()不初始化配置的內存,calloc()初始化配置的所有內存爲0;

1.3 例子

//malloc()
int * array;
if ( NULL == (array = malloc(10 * sizeof(int))) ) {
  printf("malloc failed\n");
  return(-1);
}
//calloc()
int * array = calloc(10, sizeof (int));

上述配置內存方式,不安全,使用了隱式的類型轉換,推薦使用下述的安全類型轉換

int * ptr;
ptr = (int *)malloc(10 * sizeof(int));	/* with a cast */
ptr = reinterpret_cast<int *>(malloc(10 * sizeof(int))); /* with a cast, for C++ */

2. Stack(棧)和Heap(堆)分析

進程中每個線程都有自己的堆棧,這是一段線程創建時保留下的地址區域。我們的“棧內存”即在此。至於“堆”內存,我個人認爲在未用new定義時,堆應該就是未“保留”未“提交”的自由空間,new的功能是在這些自由空間中保留(並提交)出一個地址範圍。

棧(Stack)是操作系統在建立某個進程時或者線程(在支持多線程的操作系統中是線程)爲這個線程建立的存儲區域,該區域具有FIFO的特性,在編譯的時候可以指定需要的Stack的大小。在編程中,例如C/C++中,所有的局部變量都是從棧中分配內存空間,實際上也不是什麼分配,只是從棧頂向上用就行,在退出函數的時候,只是修改棧指針就可以把棧中的內容銷燬,所以速度最快。 

堆(Heap)是應用程序在運行的時候請求操作系統分配給自己內存,一般是申請/給予的過程,C/C++分別用malloc/new請求分配Heap,用free/delete銷燬內存。由於從操作系統管理的內存分配所以在分配和銷燬時都要佔用時間,所以用堆的效率低的多。 

在Java中除了簡單類型(int,char等)都是在堆-Heap中分配內存,這也是程序慢的一個主要原因。但是跟C/C++不同,Java中分配堆-Heap內存是自動初始化的。在Java中所有的對象(包括int的wrapper  Integer)都是在堆-Heap中分配的,但是這個對象的引用卻是在棧-Stack中分配。也就是說在建立一個對象時從兩個地方都分配內存,在堆-Heap中分配的內存實際建立這個對象,而在棧-Stack中分配的內存只是一個指向這個堆-Heap對象的指針(引用)而已。

堆-Heap是指程序運行是申請的動態內存,而棧-Stack只是指一種使用堆的方法(即先進後出)。棧-Stack是先進後出的,但是對於堆-Heap而言卻沒有這個特性,兩者都是存放臨時數據的地方。 對於堆-Heap,我們可以隨心所欲的進行增加變量和刪除變量,不要遵循什麼次序,只要你喜歡。

因爲總是將堆棧兩個字分不清,所以自己還是比較喜歡用Stack和Heap進行記憶理解,專有名詞基本不需要翻譯了。


參考

【1】 C dynamic memory allocation

【2】 Memory Allocation






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章