2008-10-27 40 views
2

我正在爲Windows Mobile應用程序編寫CESetup.dll。它必須是非託管的,我沒有什麼經驗。所以我不確定我是否應該釋放我分配的內存以及我是如何做到的。釋放堆上的內存。我應該如何?

下面是我寫的函數:

Uninstall_Init(
    HWND  hwndParent, 
    LPCTSTR  pszInstallDir 
) 
{ 
    LPTSTR folderPath = new TCHAR[256]; 
    _stprintf(folderPath, _T("%s\\cache"), pszInstallDir); 
    EmptyDirectory(folderPath); 
    RemoveDirectory(folderPath); 

    _stprintf(folderPath, _T("%s\\mobileadmin.dat"), pszInstallDir); 
    DeleteFile(folderPath); 

// To continue uninstallation, return codeUNINSTALL_INIT_CONTINUE 
// If you want to cancel installation, 
// return codeUNINSTALL_INIT_CANCEL 
return codeUNINSTALL_INIT_CONTINUE; 
} 

據我瞭解,FOLDERPATH是在堆上分配。 EmptyDirectory()是我自己的函數,用於刪除目錄中的所有內容。 RemoveDirectory()和DeleteFile()是系統調用。

我的問題是我應該在函數退出之前取消分配folderPath嗎?如果我應該,我該怎麼做?

回答

3

我想你想用這個:

delete [] folderPath; 

它看起來像你分配TCHARS,數組這是有道理的,因爲它是一個字符串。在分配數組時,必須使用數組刪除操作符(通過在刪除語句中包含括號來獲取)來刪除。我很肯定你會因Treb的解決方案而導致內存泄漏。

1

是的,你應該。通過調用

delete[] folderPath; 

在你的函數結束。所有分配有new的內存必須使用delete釋放。

4

對於那些不習慣C/C++編程的人來說,有一種常見的誤解 - 當他們看到帶有指針參數的函數時,他們認爲變量必須分配爲新的。情況並非如此,局部變量是合適的並且是首選的,因爲你不必擔心它的壽命。

你可以通過做

TCHAR folderPath[256]; 

我首選的方案是使用的std :: string大大簡化你的生活,但我已經把在一個單獨的答案。

+0

你是絕對正確的。但我嘗試過,它不會爲我編譯。 – ageektrapped 2008-10-27 15:19:14

+0

我得到錯誤,如「DeleteFileW:不能將參數1從'LPTSTR [256]'轉換爲'LPCWSTR'」 – ageektrapped 2008-10-27 15:20:51

+0

啊哈 - 你聲明一個LPTSTR數組,而不是TCHAR。 – 2008-10-27 15:28:32

1

是的,你應該釋放內存。你所稱的任何功能都不會爲你做,也不應該 - 它沒有任何意義。該存儲器被分配矢量new運算符,因此應該使用矢量刪除運算符釋放,即:

delete [] folderPath;

1

它通常更好使用std :: string,或者在你的情況下std :: basic_string。在這種情況下,當最終路徑大於256個字符時,它將消除潛在的緩衝區溢出。

Uninstall_Init(
    HWND  hwndParent, 
    LPCTSTR  pszInstallDir 
) 
{ 
    std::basic_string<TCHAR> folderPath = pszInstallDir; 
    folderPath.append(_T("\\cache")); 
    EmptyDirectory(folderPath.c_str()); 
    RemoveDirectory(folderPath.c_str()); 
    folderPath = pszInstallDir; 
    folderPath.append(_T("\\mobileadmin.dat")); 
    DeleteFile(folderPath.c_str()); 
// To continue uninstallation, return codeUNINSTALL_INIT_CONTINUE 
// If you want to cancel installation, 
// return codeUNINSTALL_INIT_CANCEL 
return codeUNINSTALL_INIT_CONTINUE; 
}