Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1234314
  • 博文数量: 177
  • 博客积分: 1528
  • 博客等级: 上尉
  • 技术积分: 1891
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-15 18:03
文章分类

全部博文(177)

文章存档

2020年(1)

2018年(19)

2017年(4)

2016年(21)

2015年(40)

2014年(13)

2013年(26)

2012年(16)

2011年(37)

我的朋友

分类: LINUX

2015-01-09 18:24:07



一.概述 2


二.例子程序简要说明 2


三.server端 2


四.client端 3


五.Valgrind的使用 3


六.参考文档 4


七.备注 4



一.概述


在gSOAP的server和client端连接中,内存的处理有些是gSOAP自己处理的,有些需要我们来考虑。本文档主要就其中目前可能遇到的内存问题,做一个简要的介绍及说明。另外,简要介绍了一下内存检测工具valgirnd的使用及注意事项。


二.例子程序简要说明


例子程序实现的是client端传入一个参数num,server端返回一个字符串,是一段不知道多长的buffer,这样需要在server端动态分配空间。这段内存的管理是本文主要讨论的问题。例子的实现可能有些冗余,但是为了说明一些问题,所以做了一些多余的实现。


得到的server端名称为getmsgserver,client端名称为getmsgtest,server启动在8888端口。


三.server端


省略server端的main函数,其功能实现函数如下:


int ns__getmsg(struct soap *getmsg_soap, int num, char **msg)


{


//下面这个空间为我们自己分配的空间,所以后来需要用free显式释放,在xmail系统中可能是从mss获取到的一段buffer,例子中的1024是随意填写的


char *a=(char*)malloc(1024);


memset(a, 0, 1024);


sprintf(a, "num=%d ",num);



//下面这个空间由soap分配,在server端的main函数中由soap_end释放该空间,由soap自己来控制,还可以直接使用*msg = soap_strdup(getmsg_soap, a)实现下面3句话,但是这个函数只适用于char*的拷贝,如果是struct的copy还是使用下面的实现方式


*msg = (char*)soap_malloc(getmsg_soap, 1024);


memset(*msg, 0, 1024);



//将我们的buffer(可能是从mss获取的)拷贝到soap管理的空间中


memcpy(*msg, a, strlen(a));



//释放由我们自己分配的空间


free(a);


return 0;


}


四.client端


client端做了简单的封装,封装后的函数如下:


int getmsg( const char* server, int num, char **msg )


{


struct soap getmsg_soap;


int result = 0;


char *getmsg = NULL;


soap_init(&getmsg_soap);


soap_set_namespaces(&getmsg_soap, getmsg_namespaces);



//下面是从server端获取数据,注意,得到的buffer在调用soap_end后空间就会被释放,所以需要定义变量getmsg,不能直接将参数msg作为此处的最后一个参数。当然,如果是在使用完msg后才调用soap_end,或者不需要将msg传出,此处就可以直接将msg作为最后一个参数。


soap_call_ns__getmsg( &getmsg_soap, server, "", num, &getmsg );


if(getmsg_soap.error)


{


printf("soap error:%d,%s,%s ", getmsg_soap.error, *soap_faultcode(&getmsg_soap), *soap_faultstring(&getmsg_soap) );


result = getmsg_soap.error;


}



//将从server端得到的buffer转储到msg中


if(getmsg)


{


*msg = strdup(getmsg);


}


soap_end(&getmsg_soap);


soap_done(&getmsg_soap);


return result;


}



这样,调用完函数int getmsg( const char* server, int num, char **msg )后,需要释放最后一个参数的空间,这个与一般的c程序相同。


五.Valgrind的使用


直接在终端键入valgrind,然后回车,可以看见一些帮助,以下是几个常用的选择项,选项可以联合使用:


1. 对server端进行非法指针操作检测:


shell>valgrind ./getmsgserver 8888


在另外一个终端执行


shell>./getmsgtest 89


2. 对server端进行内存泄漏检测,在main函数的soap_end后面添加一个exit(0),以便观察server接收一次请求后退出的情况,这样可以真实查看内存是否完全释放:


shell>valgrind --leak-check=yes ./getmsgserver 8888


在另外一个终端执行


shell>./getmsgtest 89


3. 对server端进行内存检测,是否有些内存没有完全回收:


shell>valgrind –show-reachable=yes./getmsgserver 8888


在另外一个终端执行


shell>./getmsgtest 89


4. 对client端进行非法指针操作检测:


shell>./getmsgserver 8888


在另外一个终端执行


shell> valgrind ./getmsgtest 89


5. 对client端进行内存泄漏检测:


shell>./getmsgserver 8888


在另外一个终端执行


shell>valgrind --leak-check=yes ./getmsgtest 89


6. 对client端进行内存检测,是否有些内存没有完全回收:


shell>./getmsgserver 8888


在另外一个终端执行


shell> valgrind –show-reachable=yes ./getmsgtest 89


六.参考文档


1.gSOAP的内存管理


~engelen/soapdoc2.html#tth_sEc9.13



2.Valgrind的主页



七.备注


在192.168.18.233的/home/weiqiong/soap/getmsg目录下有本文讲到的例子。用法更复杂的例子参见cvs中的xmail/pmd/ws/addrbook目录下的实现,是从mss获取地址本的实现
阅读(4013) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~