使用上使用了這類指令,都要配上等量的 free() 或 delete 來釋放記憶體,
以免造成 memory leak 的狀況,當然也可以使用免 free() 的 alloca 指令。
這陣子在做某些 code 的 refactoring 時,
將某個有使用到 alloca 片段抽出來寫成新的 function
結果程式竟然就這樣發生了不正確的結果,
假設原本的片段長醬子
int main()
{
BYTE* pbtText = NULL;
pbtText = (BYTE*)alloca(4096 + 1);
ZeroMemory(pbtText, 4096 + 1);
memcpy(pbtText, pbtSource, 4096);
// 在main()中可正常使用pbtText
DoAnything(pbtText);// 在main()中呼叫其他 function 也可正常使用
return TRUE;
}
改過的片段
int main()
{
BYTE* pbtText = NULL;
GetText(&pbtText);
// 在main()無法正常使用 pbtText
return TRUE;
}
void GetText(BYTE** pbtText)
{
*pbtText = (BYTE*)alloca(4096 + 1);
ZeroMemory(*pbtText, 4096 + 1);
memcpy(*pbtText, pbtSource, 4096);
}
查了資料後發現,原來 alloca 是有個小眉角的,
alloca 所 new 出來的空間只會存在於使用他的 function 內,
所以它不用配對 free() 來釋放記憶體,而上例 pbtText 雖然是在 main() 中宣告的,
但是卻是在 GetText 中做記憶體配置,導致 main() 無法使用配置出來的空間,
所以在同一個 function 內臨時要用到記憶體使用 alloca 是不錯的選擇,
要跨 function 時就請使用 malloc 或 new 嘍。
正確的 malloc 程式如下
int main()
{
BYTE* pbtText = NULL;
GetText(&pbtText);
// 正確的使用 pbtText
free(pbtText);
return TRUE;
}
void GetText(BYTE** pbtText)
{
*pbtText = (BYTE*)malloc(4096 + 1);
ZeroMemory(*pbtText, 4096 + 1);
memcpy(*pbtText, pbtSource, 4096);
}
另外,alloca 是直接在 static 上面配置記憶體,速度比 malloc 快上許多,
但這在程式要做跨平台時移植時可能會造成困擾,
並不是所有的 OS 都可以支援 alloca 這種指令的操作,
相較之下使用 malloc 再記得 free 會保守安全許多。
沒有留言:
張貼留言