Why I get (sligtly) different outputs reading the same char* buffer using two different methods?

0

I'm writing a program in C++ to read and decode data received over TCP which I store in a char* buffer.

Method 1
Since I found useful to be able to read the buffer for debugging purposes, I firstly used this function to extract a given number of bytes from the buffer:

string MyClass::extractBytes(int a, int b) {
    string s = "";
    for (int i = a; i <= b; ++i) {
        bitset<8> b(DATA[i]);
        s += b.to_string();
    }
    return std::string(s);
}

where DATA is the char* buffer (private MyClass object member). This way I also get the correct endianness and I'm able to read the binary values if needed. I have a int cursor I increment after each operation. This method showed result that matched the expected values received from the device

Method 2
Performance is not that big of a deal in this project, but I would like to use a better approach here. I'm considering using a char pointer to run thru the buffer and get the values directly from there. Let's say I have to read a 32 bit value at index 30:

char* cursorPtr = DATA; //initializing the cursor to point the same memory address
cursorPtr += 30;
uint32_t value32 = *(reinterpret_cast<uint32_t*>(cursorPtr));
bitset<32> bitValue(swapEndianness(value32));


//SWAP FUNCTION
static uint32_t swapEndianness32(uint32_t value) {
    uint32_t result = 0;
    result |= (value & 0x000000FF) << 24;
    result |= (value & 0x0000FF00) << 8;
    result |= (value & 0x00FF0000) >> 8;
    result |= (value & 0xFF000000) >> 24;
    return result;
}

Now, if I'm going to print the output of those two methods I got almost always the same results, but sometimes they differ somehow (for method one, I used extractBytes(startPosition, endPosition)). Example output:

STRING:  00010010000000000000111100000000 00001000000001001110111100000001
VALUE:   00010000000000000000100011110000 00001000000001001110111100000001

STRING:  00010101000000000001110000000000 00001000000001001110111100000001
VALUE:   00010101000000000001110100000000 00001000000001001110111100000001

I showed blocks of 64 bits to let you know that almost everything matches (and that can't be a coincidence) except for some values. At first I supposed to have messed something with the endianness thing, so I printed a single byte. Plus, I also addressed it differently to spot pointer increments issues:

s1 = extractBytes(cursor, cursor);
s2 = uint8_t value = *(reinterpret_cast<uint8_t*>(&DATA[cursor])); //I know char is 8 bits

Still, the output sometimes is different. Another test I made was to use memcpy to extract the values from the buffer and save them to another location:

char MEM[8];
memcpy(MEM, &DATA[cursor], 8);
uint64_t value64 = *(reinterpret_cast<uint64_t*>(MEM));
log << swapEndianness64(value64);

But still the problems remains. What's the reason of this behaviour?

c++
pointers
memory
bitset
asked on Stack Overflow May 13, 2020 by Hackjaku • edited May 13, 2020 by Hackjaku

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0