Search code examples
c++arraysbinarybytereinterpret-cast

Reading 4 bytes from the end of a char array


If I have a char* array:

char* c = getBytesFromSomewhere();

I'd like to read the last 4 bytes to a uint and then the previous 4 bytes etc. I tried this:

char* end = &c[size-5];

to get a pointer to the last 4 bytes in the array and then:

unsigned int n = *(reinterpret_cast<int *>(end));

but it doesn't seem to be working.... what am I doing wrong?


Solution

  • Lets say the returned array is of size 8, it would look something like this in memory:

    +---+
    | c |
    +---+
      |
      v
      +---+---+---+---+---+---+---+---+
      | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
      +---+---+---+---+---+---+---+---+
    

    (The numbers inside is the indexes.)

    Now if you make a new variable e to point at c + size it will point point to one beyond the end of the data:

    +---+                           +---+
    | c |                           | e |
    +---+                           +---+
      |                               |
      v                               v
      +---+---+---+---+---+---+---+---+
      | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
      +---+---+---+---+---+---+---+---+
    

    If you subtract 1 from e it now points to index 7:

    +---+                       +---+
    | c |                       | e |
    +---+                       +---+
      |                           |
      v                           v
      +---+---+---+---+---+---+---+---+
      | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
      +---+---+---+---+---+---+---+---+
    

    If you subtract two (in total) e would point to index 6, subtract 3 and e would be pointing at index 5 and subtract 4 and the index pointed to would be 4. If you subtract 5 the pointer e would point to index 3:

    +---+       +---+
    | c |       | e |
    +---+       +---+
      |           |
      v           v
      +---+---+---+---+---+---+---+---+
      | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
      +---+---+---+---+---+---+---+---+
    

    And that's not four bytes from the end, that's five bytes from the end.

    So you should be doing e.g.

    char* end = c + size - 4;  /* Subtract by 4 and not 5 */
    

    You should also be careful of the endianness, if the data comes from other systems e.g. over the Internet.