简体   繁体   中英

Traversing byte string through uint16_t pointer

I have a list of uint16_t 's that has been packed into a protobuf message that looks like:

bytes values = 1;

The generated stubs for this message in C allows me to set the field with some code like:

protobufMessage.set_values(uint16ptr, sizeof(uint16_t) * amount);

In the above example, uint16ptr is a uint16_t* to the start of the value list and amount is the number of elements in that list.

Now, since I know the message is in the field and I want to be as efficient as possible, I don't want to memcpy as that I want to somehow directly access that memory and I don't want to iterate through the values one by one as cases with a large amount value would be slow. So I tried something like:

uint16_t *ptr = (uint16_t*) some_string.c_str();

This works "fine", however I don't get the same values I originally packed in. I think it might be because I am not traversing the data correctly. How should I do this properly?

Protobuf encodes your message so you can't simply read the values back from a string. But a "repeated" uint16_t should be a big blob somewhere in the message. If you knew the offset you could access the data there.

But that is still UB since the uint16_t in the protobuf message are not aligned. So on some CPUs this will be just slow, on others it will trap. The only safe way is to memcpy the data. Use the function provided by protobuf to extract the uint16_t's.

Note: Strictly speaking it's even worse since there are no objects of type uint16_t living in the message so any access would be UB. But it being a fundemantal type makes it ok-ish, if it weren't for the alignment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM