Home > Back-end >  C : Addressing each byte
C : Addressing each byte

Time:12-06

Trying to extract each byte in a short I've created. While I can print the second (or first) byte, I can't get both. With my current understanding, this should work. Hoping someone can make it clear to me what the error is here. I'm running this on windows x86, so ILP32 data format.

#include <iostream>

using namespace std;

int main()
{ 
    short i = 0x1123;
    short* p = &i;
    short* p1 = p;

    p1  ;
    
    char c = *p;
    char c1 = *p1;

    cout
        << "Short: " << hex << i << '\n'
        << "p: " << p << '\n'
        << "p1: " << p1 << '\n'
        << "c: " << hex << (unsigned int)c << '\n'
        << "c1: " << hex << (unsigned int)c1 << '\n'
        ;

    return 0;
}

Output:
Short: 1123
p: 0041FB58
p1: 0041FB56
c: 23
c1: ffffffcc

CodePudding user response:

Here is the fix:

#include <iostream>
#include <iomanip>

int main()
{
    short i = 0x1123;
    short* p = &i;
    
    char* c = reinterpret_cast<char*>( p );
    char* c1 = c   1;

    std::cout << "Short: " << std::showbase << std::hex << i << '\n'
              << "p: " << p << '\n'
              << "c: "  << static_cast<int>( *c ) << '\n'
              << "c1: " << static_cast<int>( *c1 ) << '\n';

    return 0;
}

There is no need for p1. The problem with p1 is that it adds 2 to the value of p1 and not 1 as you would expect. And that's because p1 is a pointer to short so when you increment it, it progresses by 2 (short is 2 bytes). You need to cast it to a char* so that each time you increment it, it will add 1 to the value.

Possible output:

Short: 0x1123
p: 0xb71f3ffd8e
c: 0x23
c1: 0x11

CodePudding user response:

Thank you to rustyx and Pete Becker who answered this. The program is aware that the pointer is for a type short therefore when I try to increment it automatically increments the value by 2. This behaviour can be circumvented by casting the pointer to a char.

#include <iostream>

using namespace std;

int main()
{ 
    short i = 0x1123;

    cout
        << "Short: " << hex << i << '\n'
        ;

    
    char* p = (char*)&i;        
    char c = *p;

    cout
        << "p: " << hex << (unsigned int)p << '\n'
        << "c: " << hex << (unsigned int)c << '\n'
        ;

    char* p1 = p   1;
    char c1 = *p1;

    cout
        << "p1: " << hex << (unsigned int)p1 << '\n'
        << "c1: " << hex << (unsigned int)c1 << '\n'
        ;

    return 0;
}
Output:
Short: 1123
p: 54fd54
c: 23
p1: 54fd55
c1: 11

CodePudding user response:

An alternative solution that uses no pointer trix and doesn't care about endianness.

#include <iostream>

int main()
{ 
    short i = 0x1123;

    unsigned low = i % 256;
    unsigned high = i / 256;

    std::cout << std::hex
              << "Short: " << i << '\n'
              << "low: "   << low << '\n'
              << "high: "  << high << '\n';

    return 0;
}
  • Related