0

I testing a bit with different formats and stuff like that. And we got a task where we have to put uint32_t into char*. This is the code i use:

void appendString(string *s, uint32_t append){
    char data[4];
    memcpy(data, &append, sizeof(append));
    s->append(data);
}

void appendString(string *s, short append){
    char data[2];
    memcpy(data, &append, sizeof(append));
    s->append(data);
}

From string to char is simple and we have to add multiple uints into the char*. So now i'm just calling it like:

string s;
appendString(&s, (uint32_t)1152); //this works
appendString(&s, (uint32_t)640); //this also works
appendString(&s, (uint32_t)512); //this doesn't work

I absolutely don't understand why the last one isn't working properly. I've tested multiple variations of transform this. One way always gave me output like (in bits): 00110100 | 00110101 ... so the first 2 bits are always zero, followed by 11 and then for me some random numbers.. What am i doing wrong?

Niccoo
  • 11
  • 4
  • 1
    How does `s->append` know how much data there is? Is it templated? – Ben Voigt Nov 16 '17 at 19:15
  • data is not ‚\0‘ terminated. –  Nov 16 '17 at 19:16
  • Why are you using `std::string` for binary data? Append is assuming what it is a C style string - i.e. null terminated – Ed Heal Nov 16 '17 at 19:18
  • 2
    do not use `std::string` for binary data, use `std::vector` instead – Slava Nov 16 '17 at 19:18
  • @Slava: That probably is a better idea, but `std::string` is length-based not terminator-based, and can handle embedded NUL just fine.... if used correctly. – Ben Voigt Nov 16 '17 at 19:19
  • 1
    @BenVoigt I know it can, but `std::string` has too many links with zero based strings, it would be much less error prone to use vector. For example you can override `std::ostream::operator<<` to dump binary data properly, wityhout it it would reject to printe etc. – Slava Nov 16 '17 at 19:21

1 Answers1

3

Assuming that string is std::string, then the single-argument version of std::string::append is being used, which assumes the input data is NUL-terminated. Yours is not, but append will go looking for the first NUL byte anyway.

512 is 0x00000100, which on a little endian machine is 0x00 0x01 0x00 0x00. Since the first byte is NUL, std::string::append() stops there.

Use the version of std::string::append() where you pass in the length.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720