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

前端 未结 6 521
忘了有多久
忘了有多久 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:18

    In C99, you have the stdint.h header, which contains int8_t and uint8_t types, which are guaranteed to be 8 bits (and generally are just typedefs for char). Beyond this, there is no real language level support for bytes in C or C++, in fact the standard goes out of its way to say that sizeof for example is in units of char (and not bytes). There is also the CHAR_BIT macro which tells you the number of bits in a byte, on some platforms char was 9bits for example. Of course I'm assuming by byte you mean octet.

    0 讨论(0)
  • 2021-01-18 09:21

    ((char*)a)++

    This is one of those evil Microsoft extensions. A pointer casting expression is an rvalue, but according to the C++ language rules, the increment operator only works on lvalues. g++ refuses to compile this.

    0 讨论(0)
  • 2021-01-18 09:28

    I think you are confused:

    char is 1 byte, but not defined for byte operation purpose. I believe there's another way to do this byte operation. What's the correct way to byte operation?

    What exactly are you expecting byte to mean, if not the exact same thing that char means?

    In C and in C++, chars are bytes. By definition. What is not the case is that bytes are necessarily octets. A byte contains at least 8 bits. There is no guarantee that a given platform even makes it possible to reference a chunk of memory that is exactly 8 bits.

    0 讨论(0)
  • 2021-01-18 09:28
    ((char*&)a)++;
    

    Or:

    a = (int*)((char*)a+1);
    

    I hope you know exactly what you're doing. For one thing, you're ending up with - by definition - unaligned int pointer. Depending on architecture and OS, this might be trouble.

    0 讨论(0)
  • 2021-01-18 09:29

    plz, use void*

    int g = 10;
    int *a = &g;
    printf("a : %p\n",a);
    printf("a : %p\n", ++a);
    printf("a : %p\n", (void*)((char*)a+1));
    

    a : 0xbfae35dc a : 0xbfae35e0 a : 0xbfae35e1

    0 讨论(0)
  • 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.
    0 讨论(0)
提交回复
热议问题