之前可能会问这个问题,但我找不到我需要的东西。
我的问题是,我有一个从webservice下载的数据加载的缓冲区。缓冲区采用unsigned char *形式,其中末尾没有'\ 0'。然后我有一个poco xml解析器需要一个字符串。
我尝试将它分配给字符串valgrind发现一些丢失的数据。 (见下文)
这是代码:
DOMParser::DOMParser(unsigned char* consatData, int consatDataSize,
unsigned char* lagData, int lagDataSize) {
Poco::XML::DOMParser parser;
std::string consat;
consat.assign((const char*) consatData, consatDataSize);
pDoc = parser.parseString(consat);
ParseConsat();
}
Poco xml解析器确实有一个ParseMemory,它需要一个const char *和数据大小但由于某种原因它只是给我分段错误。
更新:这是valgrind结果的一部分:
==11880== 12,272 bytes in 1 blocks are possibly lost in loss record 1,126 of 1,143
==11880== at 0x402569A: operator new(unsigned int) (vg_replace_malloc.c:255)
==11880== by 0x4491D05: std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) (in /usr/lib/libstdc+$
==11880== by 0x4493F6F: std::string::_M_mutate(unsigned int, unsigned int, unsigned int) (in /usr/lib/libstdc++.so.6.0.13)
==11880== by 0x4494109: std::string::_M_replace_safe(unsigned int, unsigned int, char const*, unsigned int) (in /usr/lib/libstdc++.$
==11880== by 0x44941AD: std::string::assign(char const*, unsigned int) (in /usr/lib/libstdc++.so.6.0.13)
==11880== by 0x804DE03: DOMParser::DOMParser(unsigned char*, int, unsigned char*, int) (DOMParser.cpp:27)
答案 0 :(得分:1)
我的问题是如何将非空终止的数据转换为字符串
使用适当的std::string
构造函数,如下所示:
std::string( (const char*) consatData, consatDataSize);
几乎等效地使用.assign()
方法:
std::string consat;
consat.assign((const char*) consatData, consatDataSize);
我意识到这会导致泄漏等问题。
你意识不到。字符串数据被复制到字符串中。没有泄漏。
注意:有人可能会说,“不要使用C风格的演员!”他们可能是对的。您可能应该使用reinterpret_cast<const char*>(consatData)
代替。我将C风格的演员阵容留在原处,因为它们起作用,并且因为原始代码使用它。
答案 1 :(得分:0)
这里有两个问题:首先,你的缓冲区不是以空值终止的。其次,它是unsigned char
而非标准char
。
consatData
指向的内存来自哪里?您是在从Web服务读取数据之前分配它,还是Web服务分配它?此外,缓冲区的大小是consatDataSize
还是Web服务读取的字节数?
看看你是否可以分配缓冲区,以便在最后自己有空间添加空终止符。如果你控制缓冲区的大小(也就是说,如果你自己分配它并只是要求webservice写入它),那么只要分配一个额外的字节并在webservice告诉你它有多少字节时就写一个空值书面。否则,我无法想象一个服务不会null终止它自己的char缓冲区...也许你没有给它足够的存储空间?
然后,将其转换为字符串follow this StackOverflow thread。至少有两个建议的解决方案:创建一个包含未签名字符的std::string
(这可能会导致兼容性问题),或者将您的未签名字符转换为签名字符并创建一个简单的std::string
。