zoukankan      html  css  js  c++  java
  • gsoap内存管理与释放

    (一)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

     

  • 相关阅读:
    新零售解决方案体系架构
    设计模式-分类
    设计模式-设计原则
    一天一个 Linux 命令(12):tree 命令
    RabbitMQ中如何保证消息的可靠传输?如果消息丢了怎么办
    为什么使用MQ?
    一天一个 Linux 命令(11):cp命令
    数据结构和算法-线性查找-二分查找
    作图工具汇总
    Git 命令大全,Git命令汇总,Git命令说明
  • 原文地址:https://www.cnblogs.com/liushui-sky/p/10482824.html
Copyright © 2011-2022 走看看