接續(xù)以前寫的:
C取時間和指標使用上的一些眉角
C在編譯時帶入的變數(shù)
一般變數(shù)不太容易觀察生命週期,還好class在建立(new)和消滅(delete)時,會呼叫建構(gòu)子(Constructor)和解構(gòu)子(Destructor),在裡面加入log觀察,幫助理解加深記憶
Lambda運算式在C#很常見,但是C的Lambda功能更多也更複雜,
這裡先用來觀察建構(gòu)子和解構(gòu)子,更多的應(yīng)用範例待以後的文章補充
#define STR(N) #N
#define XSTR(N) STR(N)
//__LINE__型態(tài)是%d,利用XSTR轉(zhuǎn)換成%s
#define _LINE_STR_ XSTR(__LINE__)
class MyClass
{
public:
MyClass()
{
printf("Constructor|%s|%s", _LINE_STR_, __FUNCTION__); //__FUNCTION__=="MyClass"
}
public:
~MyClass()
{
printf("Destructor|%s|%s", _LINE_STR_, __FUNCTION__); //__FUNCTION__=="~MyClass"
}
public:
static MyClass *Factory()
{
return new MyClass();
}
};
int main(const int argc, const char *argv[])
{
{ //_mf0只會活在大括弧內(nèi),離開大括弧時,會觸發(fā)解構(gòu)子
const MyClass _mf0();
}
{ //Lambda練習1
auto lambda = [](void) { return new MyClass(); }; //離開大括弧時,不會觸發(fā)解構(gòu)子
const MyClass *_mf1 = lambda();
delete _mf1; //觸發(fā)解構(gòu)子
}
{ //Lambda練習2
std::function<MyClass *()> func = MyClass::Factory; //離開大括弧時,不會觸發(fā)解構(gòu)子
const MyClass *_mf2 = func();
delete _mf2; //觸發(fā)解構(gòu)子
delete _mf2; //程式當?shù)?/div>
}
return EXIT_SUCCESS;
}
Lambda練習1和練習2推測是等價的語法,觀察執(zhí)行時間都小於1 usec,看不出效能差異
Lambda練習2的彈性更廣,能當作變數(shù)傳遞給別的函式使用
多delete一次就會使程式當?shù)簦瑫蓄愃埔韵碌腻e誤訊息,不同平臺訊息可能不一樣,但程式都會當?shù)簦?/div>
Exception has occurred.
Aborted
double free or corruption (fasttop): 0x0000000000646030 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x81299)[0x7ffff7052299]
當?shù)暨@點看來是沒救了,沒找到方法是能讓程式繼續(xù)往下執(zhí)行的
結(jié)論C語言是有借有還的語言,借多少就要還多少,
還少一點(Memory Leak),程式可能可以跑久一點,直到吃光機器的記憶體形成大災(zāi)難,
還多一點,立刻當?shù)魶]得救
20240129補充Lambda練習3,紀錄
1.重複使用指標,忘記釋放記憶體的情況
2.多一層NULL判斷,避免重複delete,但是程式碼會很醜
MyClass *_mcPtr = NULL;
{ //區(qū)塊1
auto lambda = [](void) { return new MyClass(); };
_mcPtr = lambda();
}
{ //區(qū)塊2
std::function<MyClass *()> func = MyClass::Factory;
_mcPtr = func(); //重複使用指標,忘記釋放區(qū)塊1(Memory Leak)
//後來發(fā)現(xiàn)以下程式碼是不好的寫法,之後再補充修正
if (_mcPtr != NULL)
{
delete _mcPtr; //觸發(fā)區(qū)塊2解構(gòu)子
}
_mcPtr = NULL;
}
if (_mcPtr != NULL) //多一層NULL判斷,避免重複delete
{
delete _mcPtr; //程式不會當?shù)簦菂^(qū)塊1變成沒用的孤兒記憶體,直到程式結(jié)束
}
_mcPtr = NULL;