c++ - 如果尝试清理,由于崩溃而不可避免的 libxml2 内存泄漏
问题描述
我们正在使用 libxml2 来针对包含“已注册”变量的 xmlcontext 解析 xpath。我们的析构函数尝试清理 xmlXPathContextPtr 和 xmlDocPtr:
~CLibXpathContext()
{
xmlXPathFreeContext(m_xpathContext); //causes crash if any vars registered
xmlFreeDoc(m_xmlDoc);
}
我们正在注册 vars,如下所示:
virtual bool addVariable(const char * name, const char * val) override
{
if (m_xpathContext )
{
xmlXPathObjectPtr valx = xmlXPathWrapCString((char*)val);
return xmlXPathRegisterVariable(m_xpathContext, (xmlChar *)name, valx) == 0;
}
return false;
}
libxml2清理代码如下:
void xmlXPathFreeContext(xmlXPathContextPtr ctxt) {
if (ctxt == NULL) return;
if (ctxt->cache != NULL)
xmlXPathFreeCache((xmlXPathContextCachePtr) ctxt->cache);
xmlXPathRegisteredNsCleanup(ctxt);
xmlXPathRegisteredFuncsCleanup(ctxt);
xmlXPathRegisteredVariablesCleanup(ctxt); // this is causing the issue
xmlResetError(&ctxt->lastError);
xmlFree(ctxt);
}
任何想法我可能做错了什么,或者如果 libxml2 代码有问题?
我们还尝试在调用 xmlXPathFreeContext 方法之前取消注册所有已注册的变量...
解决方案
您必须使用xmlXPathNewCString(const char *)
而不是xmlXPathWrapCString(char *)
. 前者创建字符串的副本,而后者将字符串的所有权转移给 XPath 对象,当 XPath 对象被销毁时释放原始字符串。
推荐阅读
- python - 无法弄清楚为什么我在尝试获取 CSV 行数时不断收到 KeyError
- sql - 需要将其转换为 MongoDB 形式
- javascript - 将复杂的对象数组操作为具有键值数组的对象
- python - AttributeError:找不到 PyAudio;检查安装(语音识别)
- python - 我使用 Paramiko 的 Python 脚本在 IDE (PyCharm) 和命令行中完美运行,但不能在 AWS Lambda 上运行
- node.js - 如何获取通过请求连接的用户的本地IP地址 - Nodejs
- android - 共享元素过渡:过渡闪烁,因为目标片段具有嵌套的滚动视图
- javascript - 根据 Parent 节点 id 或 Umbraco 中页面的当前 id 搜索内容
- selenium-webdriver - 自动打开太多 Edge 实例,并显示“错误:file_io_win.cc(180)] CreateFile settings.dat:访问被拒绝。(0x5)”
- loops - 循环遍历未知属性的 Grails 对象的所有字段