gsoap 内存泄漏 C 应用程序

0 gsoap

我们将 gsoap 用于为运行 Linux 的 blackfin 实现的 C 客户端和服务器 Web 服务。

我们不在应用程序中使用任何 malloc。但是我们看到内存使用量随着时间的推移而攀升。我们正在使用 soap_end 在通话结束时进行清理。但是当调用被反复调用时内存使用量慢慢增加,可能是因为内存碎片。这也会影响系统的性能

在不经常使用soap_malloc 的情况下,gsoap 的首选用法是什么。例如:如果我们使用静态数组等会有所帮助吗?

谢谢,

恩克尔

Dr.*_* RE 5

我不建议使用静态数据,没有必要。

要调试内存使用,请使用-DDEBUG. 运行应用程序时,您将看到三个文件:

  • SENT.log 发送的消息
  • RECV.log 收到的消息
  • TEST.log 调试日志

TEST.log对于检查消息传递问题很有用。

在运行时产生的其他有价值的信息是与内存泄漏或代码中损坏(例如溢出)的堆内存相关的错误消息。这些不太可能发生在 gSOAP 引擎中,但最好检查一下。

为确保管理数据的正确分配和解除分配:

soap_destroy(soap);
soap_end(soap);
Run Code Online (Sandbox Code Playgroud)

我正在使用自动生成的函数来分配托管数据:

SomeClass *obj = soap_new_SomeClass(soap);
Run Code Online (Sandbox Code Playgroud)

偶尔soap_malloc用于原始托管分配,或分配指针数组或 C 字符串:

const char *s = soap_malloc(soap, 100);
Run Code Online (Sandbox Code Playgroud)

但更好的是分配字符串:

std::string *s = soap_new_std__string(soap);
Run Code Online (Sandbox Code Playgroud)

和数组可以用第二个参数分配,例如一个包含 10 个字符串的数组:

std::string *s = soap_new_std__string(soap, 10);
Run Code Online (Sandbox Code Playgroud)

删除所有托管分配,soap_destroy()后跟soap_end()。之后,您可以再次开始分配并再次删除等。

如果要保留这些调用会删除的数据,请使用:

soap_unlink(soap, obj);
Run Code Online (Sandbox Code Playgroud)

现在obj可以稍后使用delete obj. 但请注意,obj该指向托管数据的所有指针成员在soap_destroy()和之后都无效soap_end()。因此,您可能必须调用soap_unlink()这些成员或冒着悬空指针的风险。

gSOAP 的一个很酷的新特性是自动为任何数据结构生成深度复制和删除功能,从而节省了大量的编码时间:

SomeClass *otherobj = soap_dup_SomeClass(NULL, obj);
Run Code Online (Sandbox Code Playgroud)

这会复制obj到非托管堆空间。这是一个深层副本,用于检查对象图中的循环并删除这些循环以避免删除问题。您还可以通过soap对 的第一个参数使用代替 NULL 来将整个(循环)托管对象复制到另一个上下文soap_dup_SomeClass

深度删除:

 soap_del_SomeClass(obj);
Run Code Online (Sandbox Code Playgroud)

这会删除obj其成员指向的数据,等等。

要使用soap_dup_Xsoap_del_X函数,请分别使用带有选项-Ec和 的soapcpp2 -Ed

原则上,静态和堆栈分配的数据也可以序列化。但请考虑改用托管堆。

希望这可以帮助。