将unsigned char * buffer分配给字符串

时间:2012-10-15 21:22:02

标签: c++ string memory char memory-leaks

之前可能会问这个问题,但我找不到我需要的东西。

我的问题是,我有一个从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)

2 个答案:

答案 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