1. 程式人生 > >改善C++ 程式的150個建議學習之建議21:儘量用new/delete代替malloc/free

改善C++ 程式的150個建議學習之建議21:儘量用new/delete代替malloc/free

在C語言中,我們已經熟悉利用malloc/free來管理動態記憶體,而在C++中,我們又有了新的工具:new/delete。你不禁會產生疑問—有了malloc/free為什麼還要new/delete 呢?使用malloc/free和使用new/delete又有什麼區別呢?首先來分析一下下面的程式碼片段:
class Object
{
public:
Object() 
{
cout << "Hello, I was born." << endl;
}
~Object()
{
cout << "Bye, I am died." << endl;
}
void Hello()
{
cout << "I am Object."<<endl;
}
};
int main()
{
cout << " Using Malloc & Free... "<<endl;
Object* pObjectA = (Object*)malloc(sizeof(Object));
pObjectA->Hello();
free pObjectA;
cout << " Using New & Delete... "<<endl;
Object* pObjectB = new Object;
pObjectB->Hello();
delete pObjectB;
return 0;
}
程式碼執行的結果為:
UsingMalloc & Free...
I am Object.
Using New & Delete...
Hello, I was born.
I am Object. 
Bye, I am died.
通過結果我們可以得知:new/delete在管理記憶體的同時呼叫了構造和解構函式;而malloc/free僅僅實現了記憶體分配與釋放。接下來,我們進行詳細討論。
malloc/free是C/C++語言的標準庫函式,而new/delete是C++的運算子。它們都可用於申請動態記憶體和釋放記憶體。由於malloc/free是庫函式,所以需要對應的標頭檔案庫函式支援。對於非內建資料型別的物件,用malloc/free無法滿足建立動態物件的要求。這是因為物件在建立的同時要自動執行建構函式,物件在消亡之前則要自動執行解構函式。由於malloc/free不是運算子,不受編譯器的控制管轄,所以不能夠把執行建構函式和解構函式的任務強加於malloc/free上。而new/delete就不同了,它們是保留字,是操作符,它們和“+”、“-”、“*”、“/”有著一樣的地位。new不僅能完成動態記憶體分配,還能完成初始化工作,穩妥地構造物件;delete不僅
能完成記憶體的釋放,還能進行物件的清理。舉個形象的例子:通過new建造出來的是一棟房子,可以直接居住;而通過malloc申請到的僅僅是一塊地皮,要想成為房子,還需要做出另外的努力。
malloc的語法是:
指標名=(資料型別*)malloc(長度); //(資料型別*)表示指標
new的語法是:
指標名= new 型別(引數); // 單個物件
指標名= new 型別[個數]; // 物件陣列
malloc函式返回的是void *型別,如果寫成:ClassA* p = malloc (sizeof(ClassA));,程式則無法通過編譯,會丟擲這樣的錯誤資訊:“不能將 void* 賦值給 ClassA * 型別變數”。所以必須通過 (ClassA *) 來進行強制轉型。相較而言,new則不存在強制轉型的問題,而且書寫更為簡單。總結起來,malloc與new之間的區別主要有以下幾點:new是C++運算子,而malloc則是C標準庫函式。通過new建立的東西是具有型別的,而malloc函式返回的則是void*,需要進行強制
轉型。new可以自動呼叫物件的建構函式,而malloc不會。new失敗時會呼叫new_handler處理函式,而malloc失敗則直接返回NULL。
free與delete之間的區別則只有以下兩點:
delete是C++運算子,free是C標準庫函式。
delete可以自動呼叫物件的解構函式,而malloc不會。
針對內建型別而言,因為沒有物件的構造與析構,所以malloc/free除了需要強制轉型之外,和new/delete所做的工作無異,用哪一個只是涉及個人喜好而已。
//declaring native type
int* i1 = new int;
delete i1;
int* i2 = (int*) malloc(sizeof(int));
free(i2);
//declaring native type array
char* c1 = new char[10];
delete[] c1;
char* c2 = (char*) malloc(sizeof(char)*10);
free(c2);
既然提到了malloc/free,不能不提一下realloc。使用realloc函式可以重新設定記憶體塊的大小,而在C++中沒有類似於realloc這樣的替代品。如果出現上述需求,所做的就是,釋放原來的記憶體,再重新申請。既然new/delete的功能不僅趕上而且超越了malloc/free,那為什麼C++標準中沒有把malloc/free淘汰出局呢?這是因為C++要遵守“對C相容”的承諾,要讓一些有價值的包含malloc/free函式庫的C程式在C++中得到重用。所以,在C++中,new/delete和malloc/
free一直並存著。不過,將malloc/free和new/delete混合使用絕對不是什麼好主意。Remember that, to new is C++; to malloc is C; and to mix them is sin. 如果用free來釋放通過new建立的動態物件,或者用delete釋放通過malloc申請的動態記憶體,其結果都是未定義的。換句話說,不能保證它會出現什麼問題。如果程式在關鍵時刻就因為這個在重要客戶面前出現問題,那麼懊悔恐怕已經來不及了。
請記住:
(1) 不要企圖用malloc/free 來完成動態物件的記憶體管理,應該用new/delete。
(2)請記住:new是C++的,而malloc是c的。如果混淆了它們,那將是件蠢事。所以new/delete必須配對使用,malloc/free也一樣。

相關推薦

改善C++ 程式150建議學習建議21儘量new/delete代替malloc/free

在C語言中,我們已經熟悉利用malloc/free來管理動態記憶體,而在C++中,我們又有了新的工具:new/delete。你不禁會產生疑問—有了malloc/free為什麼還要new/delete 呢?使用malloc/free和使用new/delete又有什麼區別呢?首先來分析一下下面的程式碼片段: cl

C/C++知識點梳理new/deletemalloc/free的區別

1.就new/delete和malloc/free的本質而言(屬性): new/delete是C++關鍵字,而malloc/free是c語言的庫函式。其次new/free在為物件開闢/釋放空間時會呼叫物件的建構函式/解構函式;而對於非內部型別malloc/fre

CC++的區別:new /deletemalloc/free

幕布分享: https://mubu.com/doc/vQfZHGsDG0 動態分配記憶體: 在程式執行中進行的,而不是在編譯就確定的 new 堆上分配記憶體 (1) 開闢T位元組大小空間: Tp =new T; size: sizeof(T)    

[C/C++] new/deletemalloc/free基本區別

/**便於遺忘時複習**/ 區別一:本質   new/delete 在C++中是運算子不是函式,需要編譯器支援。malloc/free是庫函式,需要標頭檔案支援,在C語言中使用。 區別二:開闢記憶體大小   用 new 操作符申請記憶體分配時無須指定記憶體塊的大小,編譯器會根據提供的型別資訊自行計算。

C/C++】淺析new/deletemalloc/free之間的關係

程式的記憶體分配 new/delete用法 malloc/free用法 new和malloc區別 程式的記憶體分配 一個由C/C++編譯的程式佔用的記憶體分為以下幾個部分: 1、棧區(stack)——由編譯器自動分配釋放 ,存放函式的引數值,區域

深入理解C++中的new/deletemalloc/free動態記憶體管理

# malloc/free和new/delete的區別 - malloc/free是C/C++標準庫的函式;new/delete是C++操作符。 - malloc/free只是動態分配記憶體空間/釋放空間;new/delete除了分配空間還會呼叫建構函式和解構函式進行初始化與清理資源。 - malloc/fr

讀書筆記《編寫高質量程式碼:改善C#程式的157建議

最近,在閱讀書籍《編寫高質量程式碼:改善C#程式的157個建議》,感覺寫得很不錯,特將其中的建議整理了一下,待以後隨時檢視。 現只羅列了其中的部分建議,因為書籍還沒有閱讀完,會慢慢的完善補充。 1 正確操作字串 1.1 確保儘量少的裝箱 在使用其他值引用型別到字串的轉換並

編寫高質量程式碼改善C#程式的157建議——導航開篇

為什麼要來看這本書    寫此書的作者在書中也有明確的記錄。作者一直在思考一個問題:就是到底什麼樣的程式設計書籍能夠幫助入門者快速進階?所謂“入門者”指的是已經可以使用一門語言來編寫程式,但是不太明白如何編寫高質量程式碼的人。作者回憶自己開發生涯的入門階段發現,那時候常常被以下三類問題所困擾。

深拷貝與淺拷貝---《編寫高質量程式碼改善C#程式的157建議》筆記

1.定義: 淺拷貝:將物件所有欄位複製到新物件(副本)中,其中,值型別的值被複制到副本中之後,在副本中的修改不會影響源物件的值;而引用型別欄位被複制到副本中的是引用型別的引用,而不是引用的物件,在副本中對引用型別欄位的修改會影響到源物件本身。 深拷貝:將物件中的所有欄位複製到新物件中,不過無

改善C#程式的157建議

《編寫高質量程式碼:改善C#程式的157個建議》 1:使用Framework4.0; 2:使用Release模式; 3:部分TIP由於簡單未給出原始碼; 目錄 前 言 第一部分 語言篇 第1章 基本語言要素 / 2 建議1:正確操作字串 / 2 建議2:使用預設轉型方法 / 6

每週一書-編寫高質量程式碼改善C程式程式碼的125建議

首先說明,本週活動有效時間為2016年8月28日到2016年9月4日。本週為大家送出的書是由機械工業出版社出版,馬偉編著的《編寫高質量程式碼:改善C程式程式碼的125個建議》。 編輯推薦

C#學習設計模式工廠模式

缺陷 進行 type 系列 concrete 改變 cnblogs static 優劣   最近研究一下設計模式中工廠模式的應用,在此記錄如下:   什麽是工廠模式?   工廠模式屬於設計模式中的創造型設計模式的一種。它的主要作用是協助我們創建對象,為創建對象提供最佳的方式

C語言/C+遊戲編程學習簡單 DLL 劫持,就是這麽任性

C語言 C++ C/C++ 遊戲編程C語言面向過程編程的語言;C++面向對象編程的語言。兩者有本質的區別,其實是完全不同的兩種語言,只不過C++兼容C語言而已。其中C++則一般看作是對C語言的擴展。因為C語言沒有面向對象的語法結構,而當時業界又迫切需要面向對象的編程特性,所以貝爾實驗室的開發者就為C語言添加了

程式學習路二開發工具部分功能和專案結構介紹

上一篇講到了新建專案進來,本篇主要講解開發工具部分功能和專案結構介紹,按照我的風格來,先上目錄 開發工具的部分功能簡介 小程式專案目錄簡介 以下幾個功能是我覺得比較方便喜歡的 自動儲存(設定----編輯設定-----選中修改檔案時自動儲存) console(控

改善C#程式的50種方法

摘要:為什麼程式已經可以正常工作了,我們還要改變它們呢?答案就是我們可以讓它們變得更好。我們常常會改變所使用的工具或者語言,因為新的工具或者語言更富生產力。如果固守舊有的習慣,我們將得不到期望的結果。對於C#這種和我們已經熟悉的語言(如C++或Java)有諸多共通之處的新語言,情況更是如此。人

C++語言程式設計基礎》學習陣列指標與字串

陣列元素在記憶體中順次存放,它們的地址是連續的。元素間實體地址上的相鄰,對應著邏輯次序上的相鄰。 陣列名字是陣列首元素的記憶體地址,陣列名是常量,不能被賦值 陣列名是陣列的指標,指向首個元素的地址,多維陣列的n-1維是指標一維陣列初始化: 在定義陣列時給出陣列元素的初始值:列

C++語言程式設計基礎》學習物件複製與移動

淺層複製與深層複製 淺層複製,實現物件間資料元素的一一對應複製。 深層複製,當被複制的物件資料成員是指標型別時,不是複製該指標成員本身,而是將指標所指物件進行復制。 物件的淺層複製:傳遞的是指標的值 class Point { public: Point() :x(0),

C++語言程式設計基礎》學習字串

在c++中不建議繼續使用C語言風格的陣列字串,都使用字串類string表示字串,string實際上是對字元陣列操作的封裝string類常用的建構函式 string(); //預設建構函式,建立一個長度為0的串,例:string s1; string(const char *s

C++語言程式設計基礎》學習模板與群體資料

 函式模板: 如果過載的函式,其解決問題的邏輯是一致的、函式體語句相同,只是處理的資料型別不同,那麼寫多個相同的函式體,是重複勞動,而且還可能因為程式碼的冗餘造成不一致性。 template<typename T> T abs(T x) { return x

C++語言程式設計基礎》學習棧模板

棧是隻能從一端訪問的線性群體,可以訪問的這一端稱棧頂,另一端稱棧底。棧是一種後進先出的資料結構。簡易計算器實現: Stack.h #pragma once #ifndef STACK_H #define STACK_H #include<cassert> tem