(1)記憶體的分配方式有三種
(2)如果使用堆疊儲存和靜態儲存就能滿足應用程式,就不需要使用動態儲存。
因為在堆上動態分配記憶體,需要較大的額外開銷:
(a)應用程式呼叫os中記憶體管理模組的堆管理器,搜尋其中是否有符合要求的空閒的連續位元組記憶體塊。在經過多次動態分配後,堆會變得千瘡百孔(出現大量閒散的記憶體碎片,此時,首先要進行碎片合併,才能分配成功,此時動態分配記憶體需要很長時間;
(b)動態分配記憶體失敗,需要檢查返回值或捕獲異常,這需要額外的開銷
(c)動態建立的物件可能被刪除多次,或刪除後還繼續使用,或根本就不能刪除,於是,執行時程式會吃記憶體
eg:若指標p是函式的引數,那麼在函式的入口處使用assert
(p!=null)進行檢查來避免輸入非法引數;
若使用malloc(
)或new來申請記憶體,就用if
(p==null),if
(p!=null)或者捕獲異常來進行錯誤處理;
c+
+沒有對記憶體的預設初值是什麼做出統一的規定,儘管有時候會自動初始化為零值(eg:全域性物件,靜態物件及陣列)。
無論用何種方式建立陣列,都要賦初值。
特別是for迴圈
忘記釋放記憶體或者只釋放了部分的記憶體,因此,造成記憶體的洩漏
eg:函式的return語句寫錯了,注意不要返回指向「棧記憶體」的指標或引用,因為該內存在函式結束時會被自動釋放;
問題出在getmemory(
)中,編譯器總是要為函式的每個引數製作臨時副本,指標引數p的副本是_p;
_p申請了新的記憶體,只是把_p本身的值改變了,即:指向了新的記憶體空間,但是p本身絲毫未變。
修改了_p本身的值而不是_p指向的物件。
void getmemory(char *p,
int num)
void test(void)
利用指向指標的指標及指標的引用的方法:
可以改為(利用指標的引用好理解):
void getmemory2(char **p,
int num)
//或者是char*
&pvoid test2(void)
還可以使用函式返回值來傳遞動態記憶體:
char *getmemmory3(
int num)
void test3(void)
char *getstring(void)
void test4(void)
下面的**執行不會出錯,但是不提倡這樣使用;
因為getstring2(
)內的"hello world"是字串常量,位於靜態儲存區,他在程式生命期內始終有效。
無論什麼時候呼叫getstring2(
),返回的始終是同乙個"唯讀"記憶體塊的位址。
char *getstring2(void)
//返回值修改為const char *getstring2更好
void test5(void)
參考:《高質量程式設計指南c++c語言第三版》 Spark1 6記憶體管理 一
從1.6.0版本開始,spark記憶體管理模型發生了變化。舊的記憶體管理模型由staticmemorymanager類實現,現在稱為 legacy 遺留 預設情況下,legacy 模式被禁用,這意味著在spark 1.5.x和1.6.0上執行相同的 會導致不同的行為。為了相容,您可以使用spark....
記憶體管理 記憶體管理概述
儲存器的發展方向是高速 大容量和小體積,即儲存器嘗試更高讀寫速度,更大儲存容量,更小物理體積。在計算機中,常見的儲存器有 暫存器,快取,記憶體,硬碟,一般硬碟之類的輔助儲存器又稱外存。在平均讀寫速度上,有 暫存器 快取 記憶體 外存 在單位容量 上,有 外存 記憶體 快取 暫存器 cpu處理器只能直...
《記憶體管理》 記憶體
1.c c 記憶體分布 我們先來看下面的一段 和相關問題 int globalvar 1 static int staticglobalvar 1 void test char char2 abcd char pchar3 abcd int ptr1 int malloc sizeof int 4 ...