(一)gSoap客戶端調用WebService完成后注意內存釋放順序
1 //Soap資源清理 2 soap_destroy(soap_sp.get()); //清理反序列化的類實例 3 soap_end(soap_sp.get()); //清理反序列化的數據 (除類實例) 和臨時數據清理 4 soap_done(soap_sp.get()); //重置和分離上下文: 關閉網絡連接和刪除回調
釋放順序不能錯,否則導致內存泄露
(二)gsoap內存管理
gsoap分配的內存在內部有一個鏈表維護,在調用soap_destroy時會釋放所有手動分配的內存,因此你無需釋放內存,只需要檢查soap_malloc成功與否就可以了.
如果你只用soap_malloc分配內存,並且發生了內存泄露且值是一個比較大的值時,請檢查你使用soap_malloc分配的內存使用時是否越界.如發生越界行為,將無法釋放soap.
1 /************************************************************************************* 2 * 內存分配函數 3 */ 4 //分配指定大小的內存 5 void * soap_malloc(struct soap *soap, size_t n) 6 //復制字符串 7 char * soap_strdup(struct soap *soap, const char *s) 8 //復制寬字節字符串 9 char * soap_wstrdup(struct soap *soap, const wchar_t *s) 10 //創建一個soap對象,並使用默認值初始化.僅C++,C不適用 11 T * soap_new_T(struct soap *soap) 12 //創建指定大小soap對象數組,並使用默認值初始化.n=-1時只創建一個soap對象,僅C++,C不適用 13 T * soap_new_T(struct soap *soap, int n) 14 //其它不常用就不寫了 15 /*************************************************************************************/ 16 17 18 /************************************************************************************* 19 * 釋放資源函數 20 */ 21 //刪除所有上下文管理的對象,實際上就是刪除soap_malloc分配的內存資源.必須在soap_end之前調用,適用於C和C++ 22 void soap_destroy(struct soap *soap) 23 //清理反序列化的數據和臨時數據(不包含上下文管理的對象),適用於C和C++ 24 void soap_end(struct soap *soap) 25 //刪除臨時數據但保持反序列化的數據不變,適用於C和C++,不常用 26 void soap_free_temp(struct soap *soap) 27 //提前釋放你用內存分配函數(如soap_malloc)分配的內存,適用於C和C++.你不釋放也沒關系,調用soap_destroy時也會釋放 28 void soap_dealloc(struct soap *soap, void *p) 29 //從gsoap上下文管理對象斷開p對象,此時p對象必須由你手動調用free釋放,適用於C和C++. 30 int soap_unlink(struct soap *soap, const void *p) 31 //完成上下文, 但不刪除任何托管對象或數據 32 void soap_done(struct soap *soap) 33 //最后確定並釋放上下文 (使用 soap _ new 或 soap _ copy 分配的上下文), 但不刪除任何托管對象或數據。 34 void soap_free(struct soap *soap) 35 /*************************************************************************************/
釋放內存正確的姿勢
1 //soap需要復用時的清理方法 2 #define SE_soap_clear(soap_) do {\ 3 if(NULL!=soap_){\ 4 soap_destroy(soap_);\ 5 soap_end(soap_);\ 6 }\ 7 } while (0); 8 //完全釋放soap 9 #define SE_SAFE_SOAP(soap)\ 10 do {\ 11 if(NULL !=soap) { \ 12 soap_destroy(soap);\ 13 soap_end(soap);\ 14 soap_done(soap);\ 15 soap_free(soap);\ 16 soap= NULL; \ 17 } \ 18 } while (0) 19 20 struct soap *ctx = NULL; 21 char *ptr = NULL; 22 23 ctx = soap_new1(SOAP_C_UTFSTRING); 24 //提前釋放ptr 25 ptr = soap_malloc(ctx, 100); 26 if(NULL != ptr){ 27 soap_dealloc(ctx, ptr);ptr = NULL; 28 } 29 //分離ptr 30 ptr = soap_malloc(ctx, 100); 31 if(NULL != ptr){ 32 soap_unlink(ctx, ptr); 33 //此時需要手動釋放ptr 34 free(ptr);ptr=NULL; 35 } 36 //調用soap_destroy時釋放 37 ptr = soap_malloc(ctx, 100); 38 //如果你的ctx需要復用,調用 39 SE_soap_clear(ctx) 40 //否則調用 41 SE_SAFE_SOAP(ctx); 42 ---------------------
轉自:https://blog.csdn.net/kmblack1/article/details/84341987
(三)內存管理
C/C++最大的麻煩,也是最大的優點是它要求用戶自己管理內存。我們在實現web service方式時,同樣需要考慮內存的分配與釋放。
分配內存有兩類:
- 分配n個字節,采用
void*soap_malloc(struct soap *soap, size_tn)
- 分配某個類,采用
Class*soap_new_Class(struct soap*soap) 一個類
Class*soap_new_Class(struct soap *soap, intn) n個類
這里的類是通訊xml中定義的元素,在response構造時,必然要創建若干此類元素。為簡化類的創建,可定義如下宏:
#defineNEW_ELEMENT(classtype) soap_new_##classtype(GetSoapStruct(),-1)
#defineNEW_ELEMENT_X(classtype,n) soap_new_##classtype(GetSoapStruct(),n)
其中 GetSoapSturct()是返回繼承的或包含的structsoap結構,對繼承方式的代碼,它的定義如下:
struct soap *GetSoapStruct() { return(struct soap*)this; }
在我們的Web方法實現中,可以隨意使用上面的new方法,在每次web方法完結后,調用soap_destroy(structsoap *soap) ,它會為我們清除掉這部分內存。
gsoap中有若干釋放內存的方法,幾個有用的函數(還有其它的,忽略)及其說明如下:
Function Call |
Description |
soap_destroy(struct soap *soap) |
釋放所有動態分配的C++類,必須在soap_end()之前調用。 |
soap_end(struct soap *soap) |
釋放所有存儲臨時數據和反序列化數據中除類之外的空間(soap_malloc的數據也屬於反序列化數據)。 |
soap_done(struct soap *soap) |
Detach soap結構(即初始化化soap結構) |
soap_free(struct soap *soap) |
Detach 且釋放soap結構 |
上表中,動態分配的C++類,指上面用"soap_new"分配的類;臨時數據是指那些在序列化/反序列化過程中創建的例如hash表等用來幫助解析、跟蹤xml的數據;反序列化數據是指在接收soap過程中產生的用malloc和new分配空間存儲的數據。在gsoap中,純數據空間與類空間管理不同,采用兩個方法,可以保留soap的反序列化數據(這時你需要自己釋放)。
轉自:https://www.cnblogs.com/liushui-sky/p/9723397.html