Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why does pointer arithmetic produce incorrect results?

I am trying to move a pointer forward 4096 bytes at a time like so:

#include <stdint.h>
#include <stdio.h>
void calculate(void* a)
{
    uintptr_t stride = 4096; 
    uint64_t *buff = (uint64_t*)a;
    for (uintptr_t offset = 0; offset < 20000; offset += stride)
    {
        fprintf(stdout, "%s: stride = 0x%x offset = 0x%x buff = %p offset+buff = %p\n", __func__, stride, offset, buff, offset+buff);
    }
}

int main(void)
{
    void* address = 0x7f5b588d1000;

    calculate(address);

    return 0;
}

However this is the current output:

calculate: stride = 0x1000 offset = 0x0 buff = 0x7f5b588d1000 offset+buff = 0x7f5b588d1000
calculate: stride = 0x1000 offset = 0x1000 buff = 0x7f5b588d1000 offset+buff = 0x7f5b588d9000

As you can see it says:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

0x7f5b588d1000 + 0x1000 = 0x7f5b588d9000

Why is this computation wrong? The result should obviously be 0x7f5b588d2000

>Solution :

Pointer arithmetic is done in units of the pointed-to type. This means adding stride to a pointer of type uint64_t moves the pointer up by stride elements, not stride bytes, so the pointer value increases by stride * sizeof(uint64_t).

You should change the type of buff to uint8_t * or simply unsigned char *. That will move the address up by the given number of bytes.

uint8_t *buff = a;

Note also that it’s not necessary to cast to or from a void *.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading