将 unsigned char* 缓冲区分配给字符串

Posted

技术标签:

【中文标题】将 unsigned char* 缓冲区分配给字符串【英文标题】:Assigning unsigned char* buffer to a string 【发布时间】:2012-10-15 21:22:01 【问题描述】:

之前可能有人问过这个问题,但我找不到我需要的确切内容。

我的问题是,我有一个从 web 服务下载的数据加载的缓冲区。缓冲区采用 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)

【问题讨论】:

我在任何地方都没有看到问题。你有什么问题? 不错。我可能会用不好的方式提出我的问题。我的问题是如何获取非空终止为字符串的数据。 感谢您提出问题。请记住,*** 是一个问答网站,而不是问题和解决方案网站。我已经在下面回答了你的问题。 查看 valgrind 输出后,我想知道您的程序究竟是如何退出的。它会从ParseConsat()返回吗? 【参考方案1】:

我的问题是如何获取不为空的数据以字符串结尾

使用适当的std::string 构造函数,如下所示:

std::string( (const char*) consatData, consatDataSize);

几乎等效地使用.assign() 方法:

std::string consat;
consat.assign((const char*) consatData, consatDataSize);

我意识到这会导致泄漏等问题。

你理解错了。字符串数据被复制到字符串中。没有泄漏。

注意:有人可能会说,“不要使用 C 风格的强制转换!”他们可能是对的。您可能应该改用reinterpret_cast&lt;const char*&gt;(consatData)。我保留了 C 风格的转换,因为它们可以工作,而且您的原始代码使用它。

【讨论】:

该 valgrind 结果表明存在其他问题,阻止 consat 的析构函数运行。可能的情况包括longjmp()exit() 或段错误。【参考方案2】:

这里有两个问题:首先,您的缓冲区不是以空值结尾的。其次,它是unsigned char,而不是标准的char

consatData指向的内存从哪里来?您是在从 Web 服务读取数据之前分配它,还是由 Web 服务分配它?另外,consatDataSize 是缓冲区的大小,还是 web 服务读取的字节数?

看看您是否可以分配缓冲区,以便您有空间自己在最后添加空终止符。如果您控制缓冲区的大小(也就是说,如果您自己分配它并且只要求 web 服务写入它),那么只需分配一个额外的字节并在 web 服务告诉您它有多少字节时向它写入 null书面。否则,我无法想象一个服务不会终止它自己的字符缓冲区......也许你没有给它足够的存储空间?

然后,将其转换为字符串,follow this *** thread。至少有两种建议的解决方案:创建一个包含无符号字符的std::string(这可能会导致兼容性问题),或者将您的无符号字符转换为有符号字符并创建一个普通的简std::string

【讨论】:

好吧,我使用 CURL 写入函数返回缓冲区: size_t URL::_writeFunction(void ptr, size_t size, size_t nmemb) int new_size = buffer_size + (size * nmemb); unsigned char new_buffer = new unsigned char[new_size]; memcpy(新缓冲区,缓冲区,缓冲区大小); memcpy(new_buffer + buffer_size, ptr, (size * nmemb));删除缓冲区;缓冲区 = 新缓冲区;缓冲区大小 = 新大小;返回(大小 * nmemb);

以上是关于将 unsigned char* 缓冲区分配给字符串的主要内容,如果未能解决你的问题,请参考以下文章

在 C 中读取和写入 unsigned char 的缓冲区到文件?

SWIG 将 unsigned char* 转换为 20 字节缓冲区 Java 结构

将 unsigned char 缓冲区与 node-ffi 一起使用

将从 SHA1 返回的 unsigned char* 转换为字符串

C#将char和char数组分配给字符串?

使用“unsigned char”指向原始数据缓冲区时需要了解内存管理