将 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<const char*>(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 一起使用