關於new和delete,malloc和free。我們都知道,是在不同的語言裡面做相應的記憶體的開闢和釋放工作的,那麼這篇博文就來好好的了解一下他們的區別和工作原理吧~
1、引言
首先,我們還是寫乙個我們經常使用的在c語言中動態開闢的方式
int
main()
*p =10;
free
(p);
return0;
}
其中malloc 和free都是函式。他們的函式原型如下:
void* malloc(size_t size);
void free(void* ptr);
從以上的函式原型就可以分析出為什麼要進行(int*)強轉了,主要就是因為void為半開半閉的區間不安全,所以要強轉成int的全封閉區間
由此,我們可以總結出malloc的不足。
2、malloc的不足
返回值型別不安全
【舉個栗子】以下這種情況就出現了越界
int* p = (int*)malloc(1)
大小是使用者來控制從而造成空間浪費或者不足
malloc只是單純的開闢空間二沒有做初始化
2、陣列中用法
int* q = (int*)malloc(sizeof(int) * 20);
if (p == nullptr)
free(p);
1、簡單的開闢記憶體c中:
int* p = (int*)malloc(sizeof(int));
c++中:
使用new關鍵字來開闢記憶體並做初始化,初始化的方式通常是在型別後面加小括號。具體如下:
int *p = new int(20);
2、動態開闢陣列1、開闢一維陣列
c中:
int* p = (int*)malloc(sizeof(int)*10);
free(p)
c++中:
使用new關鍵字,使用型別【size】的方式,具體如下:
int *p = new int;
delete p;
如果還要對陣列進行零初始化,則使用以下的方式
int *p = new int();
1、開闢二維陣列
c語言中
int **p = (int**)malloc(sizeof(int*)*3);
for(int i =0;i<4;i++)
free(p);
c++中
int** cp = new int*[3]();
for(int i = 0;i<3;i++)
for(int i =0;i<3;i++)
delete cp;
3、記憶體不出處理機制c中:
一旦記憶體不足,如果開闢失敗給指標返回乙個空。
int* p = (int*)malloc(sizeof(int));//只開闢
if (p == nullptr)//由空指標和返回值來判斷開闢失敗
free(p);
c++中:
new開闢記憶體失敗,是通過丟擲bad_alloc型別的異常來判斷的
try
catch (const bad_alloc & e)
4、常量記憶體塊c中
:如果我們用以下的方式開闢並不是開闢的常量記憶體塊
const int* p = (int*)malloc(sizeof(int));
free();
原因是,一共生成了8個位元組,其中堆上開闢了4個位元組,棧上系統開闢了4個位元組。他們之間的關係如下圖:
c++中:
可以通過new開闢常量記憶體塊,具體如下:
const int* cpp = new const int(10);
delete cpp;
【思考】在使用過程中為什麼不能直接操作堆記憶體,要通過指標的方式指向間接操作堆記憶體?
因為,一般的我們在表示式層面都是通過變數名來操作記憶體的,但是堆記憶體並沒有變數名。只能把堆記憶體的所有權交給棧上乙個有變數名的指標來進行管理,通過指標來間接操作堆記憶體。如下圖所示:
開闢和釋放記憶體區的函式
1.malloc 函式 原型 void malloc unsigned size 其功能是在記憶體的動態儲存區中分配長度為size個位元組的連續空間。其返回值 1 分配空間的起始位址 分配成功 2 空指標null 分配失敗,一般是沒有空間 2.free p 函式 該函式表示釋放由p指向的記憶體區,是...
記憶體的動態開闢與釋放
malloc free與new delete 1 new會拋異常,但是malloc不會拋異常 2 new delete屬於操作符,但是malloc free屬於函式 3 new申請空間的時候會呼叫建構函式進行初始化,malloc不會 delete釋放記憶體時會呼叫析構函式,free只是切斷了指向關係...
delete釋放new 開闢的記憶體
直接看下面這道題 使用 char p new char 10 申請一段記憶體,然後使用delete p釋放,有什麼問題?a 會有記憶體洩露 b 不會有記憶體洩露,但不建議用 c 編譯就會報錯,必須使用delete p d 編譯沒問題,執行會直接崩潰 這道題題目開闢的是10個char型別的空間,因為是...