What's the correct way to add 1 byte to a pointer in C/C++?

前端 未结 6 558
忘了有多久
忘了有多久 2021-01-18 08:53

I\'m using this code to move pointer by 1 byte now, but I\'m feeling something unclear..

int* a = (int*)malloc(sizeof(int));
void* b = ((char*)a)+1;   
         


        
6条回答
  •  不要未来只要你来
    2021-01-18 09:38

    You should not do this. Many architectures have data alignment requirements. For example, dereferencing a pointer not aligned to a word boundary on a SPARC machine, will crash the program with a Bus Error (SIGBUS).


    The portable way to split your int into bytes is by using bitwise operations (assuming 8-bit bytes):

    uint8_t b3 = 0x12, b2 = 0x34, b1 = 0x56, b0 = 0x78;
    uint32_t a;
    
    a = (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
    
    printf("%08X\r\n", a);
    
    a = 0x89ABCDEF;
    
    b3 = (a >> 24) & 0xFF;
    b2 = (a >> 16) & 0xFF;
    b1 = (a >> 8) & 0xFF;
    b0 = a & 0xFF;
    
    printf("%02X%02X%02X%02X\r\n", b3, b2, b1, b0);
    

    The same can be non-portably achieved with type punning tricks through unions, such as:

    typedef union {
        uint32_t val;
        uint8_t  bytes[4];
    } DWORD_A;
    
    typedef union {
         uint32_t val;
         struct {
             unsigned b0:8;
             unsigned b1:8;
             unsigned b2:8;
             unsigned b3:8;
         };
    } DWORD_B;
    

    However, this technique leads to implementation defined behaviour and thus is not recommended:

    • Byte order depends on host system's endianness.
    • Packing of the bit fields is not portable.
    • Added complexity/overhead due to code generated by the compiler to prevent misaligned access.
    • Alignment issues, on implementations that don't prevent them.

提交回复
热议问题