Assigning unsigned char* buffer to a string

喜你入骨 提交于 2021-01-29 06:03:20

问题


This question might be asked before but I couldn't find exactly what I need.

My problem is, I have a buffer loaded by data downloaded from a webservice. The buffer is in unsigned char* form in which there is no '\0' at the end. Then I have a poco xml parser needs a string.

I tried assigning it to string valgrind found some lost data. (see below)

here is the code:

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 parser does have a ParseMemory which need a const char* and size of data but for some reason it just gives me segmentation fault.

Update: Here is a part of valgrind result:

==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)

回答1:


My question is how to get the data which is not null terminated to a string

Use the appropriate std::string constructor, like this:

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

Nearly equivalently, use the .assign() method:

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

I realized it would cause problem such as leaking.

You realize incorrectly. The string data is copied into the string. There is no leak.

Note: Someone may say, "Don't use C-style casts!" They are probably right. You probably should use reinterpret_cast<const char*>(consatData) instead. I left the C-style casts in place because they work, and because your original code uses it.




回答2:


There are two issues here: first, your buffer is not null-terminated. Second, it's of unsigned char rather than the standard char.

Where does the memory pointed to by consatData come from? Do you allocate it before reading data from the web service, or does the webservice allocate it? Also, is consatDataSize the size of the buffer, or the number of bytes read by the webservice?

See if you can allocate the buffer such that you have room to add the null terminator yourself at the end. If you control how large the buffer is (that is, if you allocate it yourself and just ask the webservice to write to it), then just allocate an extra byte and write a null to it once the webservice tells you how many bytes it has written. Otherwise, I cannot imagine that a service won't null-terminate its own char buffers... maybe you're not giving it enough storage?

Then, to convert it to a string, follow this StackOverflow thread. There are at least two proposed solutions: create a std::string containing unsigned chars (which may cause compatibility issues), or cast your unsigned chars to signed chars and create a plain jane std::string.



来源:https://stackoverflow.com/questions/12904221/assigning-unsigned-char-buffer-to-a-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!