[C/C++]_[中級]_[使用智慧指標的方式釋放malloc出來的堆空間]
阿新 • • 發佈:2019-01-30
場景:
1. 使用auto_ptr 的方式可以wrap類物件, 之後在方法結束後可以自動釋放物件, 參考;這樣在有條件判斷的語句時可以省掉free語句或CloseHandle.
2.C++的特性之一就是類物件(非返回值的物件)在方法結束後會自動呼叫解構函式,這樣在解構函式裡可以放一些釋放資源的操作.
3. 這裡實現了一個類似auto_ptr的類的實用Wrap類,可以參考根據自己需要自定義特定的Wrap類.auto_ptr的壞處之一就是隻支援new出來的物件,
之二是不能刪除陣列. delete []
4. 恰當使用WrapObject能有效的減少記憶體洩漏,因為在很多C程式設計裡, 太多的if語句在return前需要釋放物件,很容易就會出錯或多次釋放。
檔案 wrap_object.h
#ifndef __WRAP_OBJECT #define __WRAP_OBJECT #include <stdlib.h> #include <Windows.h> template<BOOL (WINAPI* WrapHandleFunc)(void*)> class WrapHandle { public: WrapHandle(void* data):data_(data){} ~WrapHandle() { if(data_) { WrapHandleFunc(data_); data_ = NULL; } } private: void* data_; }; class WrapMalloc { public: WrapMalloc(void* data):data_(data){} ~WrapMalloc() { free(data_); data_ = NULL; } void Reset() { free(data_); data_ = NULL; } private: void* data_; }; #endif
使用方式:
// Specify an HTTP server. const char* www = "www"; std::string URLADDR = DhOptionDomain::GetValue("url:brand"); const char* www_start = strstr(URLADDR.c_str(),www); if( !hSession ) { return kNetworkError; } WrapHandle<WinHttpCloseHandle> session_wh(hSession); wchar_t* www_start_unicode = ConvertUtf8ToUnicode(www_start); WrapMalloc www_wm(www_start_unicode); hConnect = WinHttpConnect( hSession, www_start_unicode, INTERNET_DEFAULT_HTTP_PORT, 0 ); // Create an HTTP request handle. if(!hConnect ) { return kNetworkError; } WrapHandle<WinHttpCloseHandle> connect_wh(hConnect); hRequest = WinHttpOpenRequest( hConnect, L"GET", L"/win-update.xml", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_REFRESH ); // Send a request. if(!hRequest) { return kNetworkError; } WrapHandle<WinHttpCloseHandle> request_wh(hRequest); bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0 ); // End the request. if(!bResults ) { return kNetworkError; } bResults = WinHttpReceiveResponse( hRequest, NULL );
注意: 如果沒有WrapObject的話你就得記得在if裡釋放不斷增加的 Handle物件,它是提高程式質量的好處之一,建議直接用到專案裡.