我正在为它编写Web服务器和客户端测试存根。我对参数的内存管理有疑问。
从我的客户端我调用soap函数ns1_func1(输入* pInput,输出* pOutput) 现在输入和输出类都包含指向其他结构的指针。
例如
类输出 { class abc * p1; class def * p2; };
我的问题是 - 谁负责内存分配?客户端负责输入内存分配,服务器负责输出内存管理吗?
现在我的客户端代码看起来像这样
client_fn()
{
...
input inp1;
output * pOutput = NULL;
ns1_func1(&inp1, pOutput);
if(pOutput == NULL)
{
cout<<"pOut is NULL\n";
return ERR;
}
else
{
// retrive output values from pOutput
}
...
}
尽管使用soap_new_Output(soap,-1)从服务器分配pOutput,但在调用ns1_func1之后,我总是将pOutput视为NULL。
另外,我的理解是我们应该使用soap_new_X来分配内存,当我们调用soap_destroy时会自动解除分配。如果我错了,请纠正我。
基本上我很难知道在这种情况下谁应该照顾内存分配/释放。
任何帮助都会很棒。
答案 0 :(得分:1)
因为客户端和服务器通常是不同的进程或不同的机器,所以它们各自负责自己的内存管理。客户端必须为其输入参数分配内存,gsoap然后序列化以发送到服务器。
服务器反序列化输入参数,分配所需的任何内存。它为其输出分配内存,gsoap序列化以发送回客户端。客户端反序列化服务器的响应,分配它所需的任何内存。
你肯定需要使用soap_malloc(等)进行内存分配,这就是gsoap库可以跟踪SOAP调用清理时需要释放的内容的唯一方法。
在您给出的特定ns1_func1示例中,服务器分配响应,生成的客户端代码应该分配它需要的任何内存。该调用的WSDL可能有问题,生成的客户端代码不是您所期望的。
答案 1 :(得分:0)
感谢Denton,
我面临的问题是在服务器中,我使用soap_new_abc和soap_new_def为abc和def类分配内存。这些在清理期间不会被释放。在清理部分,我正在调用soap_destroy,soap_end和soap_free。根据gsoap文档,soap_free应该调用通过soap_new_X分配的类的〜,但这不会发生。我实际上把DEBUG语句放在了soapC.cpp中的ctors和~tor中。 ctor中的DEBUG语句正在出现,但不会出现在那些语言中。所以我担心可能会有内存泄漏。
在soap_free清理过程中是否应该自动调用soap_delete_X?
答案 2 :(得分:0)
ns1_func1的签名是什么?是ns1_func1(输入*,输出*)还是ns1_func1(输入*,输出*&amp;)?对于第一种情况,您将永远无法获得非null值。
答案 3 :(得分:0)
执行此代码后:
output * pOutput = NULL;
ns1_func1(&inp1, pOutput);
无论ns1_func是什么,pOutput 总是为NULL。您正在将pOutput的值传递给函数,在本例中为NULL。如果不知道pOutput的地址(写为&amp; pOutput),该函数无法更改该值。
ns1_func1要求指向“输出”结构的指针,因为这是它想要写入输出数据的地方。这意味着您需要在堆栈上分配该空间:
output theOutput;
output * pOutput = &theOutput;
ns1_func1(&inp1, pOutput);
或在堆上:
output * pOutput = malloc(sizeof(output));
ns1_func1(&inp1, pOutput);
...
free(pOutput);
如果ns1_func1要为您分配内存,则必须返回指向输出结构的指针。要做到这一点,它需要询问该指针的地址,或指向指针的指针。换句话说,声明如下:
output * pOutput = NULL;
different_ns1_func1(&inp1, &pOutput);
if (pOutput != NULL) {
...
free(pOutput);
}
很抱歉,如果这有点令人困惑,所有关于指针指针的讨论,但你的问题的基本答案是你必须为写入的函数分配内存因为函数要求输入数据的地址而不是指向数据的地址。