new的三種形式
new operator
new操作符嫌术,用于動態(tài)分配內(nèi)存并進行初始化献烦,不能被重載彤敛,new operator首先會申請內(nèi)存与帆,然后調(diào)用構(gòu)造函數(shù)進行初始化,這與C中的malloc是有區(qū)別的墨榄。malloc只負(fù)責(zé)申請內(nèi)存玄糟,不會進行初始化操作。
operator new
標(biāo)準(zhǔn)庫的函數(shù)袄秩,只分配內(nèi)存而不進行初始化阵翎,可以重載。operator new與malloc的作用是一樣的之剧,只是負(fù)責(zé)內(nèi)存的申請郭卫。
placement new
在指定的內(nèi)存上構(gòu)造對象。由于內(nèi)存是指定的背稼,所以該new不要delete贰军,而是調(diào)用其析構(gòu)函數(shù)析構(gòu)即可。用的較少蟹肘,即便使用词疼,也會封裝在特定類中使用。
關(guān)系
new operator會調(diào)用operator new進行內(nèi)存的申請帘腹,而后自行調(diào)用構(gòu)造函數(shù)進行初始化寒跳。
delete的二種形式
delete operator
delete operator與new operator對應(yīng),為關(guān)鍵字竹椒,不能被重載童太,會首先調(diào)用對象的析構(gòu)函數(shù)進行析構(gòu),然后進行內(nèi)存的釋放。
operator delete
標(biāo)準(zhǔn)庫的函數(shù)书释,只釋放內(nèi)存不會析構(gòu)翘贮,可以重載。與free作用一樣爆惧。delete operator會首先調(diào)用析構(gòu)函數(shù)狸页,然后調(diào)用operator delete進行內(nèi)存釋放。
內(nèi)存泄漏
內(nèi)存泄漏(Memory Leak)是指程序中己動態(tài)分配的堆內(nèi)存由于某種原因程序未釋放或無法釋放扯再,造成系統(tǒng)內(nèi)存的浪費芍耘,導(dǎo)致程序運行速度減慢甚至系統(tǒng)崩潰等嚴(yán)重后果。簡單說也即new出的對象沒有被delete掉熄阻,這對C++從業(yè)者非常常見斋竞,而重載new和delete對于檢測這種問題非常有幫助。
思想:在new時秃殉,將指針地址和申請內(nèi)存發(fā)生的文件及行號保存在map中坝初,在delete中利用指針地址進行擦除,最后map中保留的信息即為沒有被釋放的信息钾军。
#include <iostream>
#include <map>
#include <string>
#include <sstream>
using std::cout;
using std::endl;
using std::map;
using std::string;
using std::stringstream;
class MemoryLeakDetect{
public:
static MemoryLeakDetect& instance(){
static MemoryLeakDetect detect;
return detect;
}
void insert(void* ptr, const char* file, int line){
std::ostringstream ss;
ss<<file<<line;
record[reinterpret_cast<int>(ptr)] = ss.str();
}
void erase(void* ptr){
record.erase(reinterpret_cast<int>(ptr));
}
void print(){
for(auto pair : record){
cout<<pair.second<<" memory leakage"<<endl;
}
}
private:
MemoryLeakDetect(){
}
map<int, string> record;
};
void* operator new(std::size_t size, const char* file, int line) {
cout<<"new"<<size<<endl;
void* ptr = malloc(size);
MemoryLeakDetect::instance().insert(ptr, file, line);
return ptr;
}
void* operator new[](std::size_t size, const char* file, int line){
cout<<"new[]"<<size<<endl;
void* ptr = malloc(size);
MemoryLeakDetect::instance().insert(ptr, file, line);
return ptr;
}
void operator delete(void* ptr){
free(ptr);
MemoryLeakDetect::instance().erase(ptr);
ptr = nullptr;
}
void operator delete[](void* ptr) {
free(ptr);
MemoryLeakDetect::instance().erase(ptr);
ptr = nullptr;
}
#define new new(__FILE__, __LINE__)
class A{
public:
A(){
cout<<"construct"<<endl;
}
~A(){
cout<<"destruct"<<endl;
}
};
int main(){
int* p1 = new int;
int* p2 = new int[4];
A* a1 = new A;
A* a2 = new A[1];
delete p1;
delete[] p2;
delete a1;
delete[] a2;
//MemoryLeakDetect::instance().print();
}
CMakeLists.txt:
cmake_minimum_required (VERSION 2.8)
add_definitions(-std=c++11)
add_definitions(-fpermissive)
add_executable(demo main.cc)
WalkeR_ZG