user3672051
user3672051

Reputation:

Overlapping Pointers

I have a case in which I have a uint64_t*, a char* (6 chars long), and a uint16_t* that point to the addresses x, x+2, and x respectively. So if the char* points to "This i" then the uint16_t* should point to the value 0 dec, and the uint64_t* should point to the value 115, 588, 096, 157, 780 dec.

But when I look at these values I am getting 0 dec for the uint64_t I do not understand why this would be. Could someone explain?

Edit (added code):

FILE *file = fopen("/Users/Justin/Desktop/test.txt", "rb");
uint64_t *window = malloc(8);
char *buffer = (char*)(window+2);
uint16_t *data = (uint16_t*)window;
uint16_t *read = (uint16_t*)(window+6);

fread(buffer, 6, 1, file);

printf("%p\n", window);
printf("%p\n", buffer);
printf("%p\n", data);
printf("%p\n", read);
printf("%s\n", buffer);
printf("%llu\n", *window);

and the output is:

0x100105440
0x100105450
0x100105440
0x100105470
This i
0

Upvotes: 1

Views: 1330

Answers (3)

Dale Wilson
Dale Wilson

Reputation: 9434

In addition to the pointer math issues that @duskwuff pointed out and @Barry clarified, there is also another issue. The answer you get will depend on the computer architecture on which this code runs.

On big-endian machines you'll get one answer, on little-endian machines you'll get a different answer.

Oh, and one more thing. Writing buffer using %s is very dangerous. If there are no zero bytes in the data read from the file, it will wander through memory until it finds one.

Upvotes: 0

Barry
Barry

Reputation: 303367

I think you're misunderstanding what the +2 does here:

uint64_t *window = malloc(8);
char *buffer = (char*)(window+2);

It helps to visualize the data that we got back from malloc, using | to help show 8-byte boundaries:

|-------|-------|-------|-------|-------|-------|-------|-------
^
window

Now, buffer doesn't point two bytes ahead of window. It points two uint64_t's ahead. Or in other words, ((char*)window) + 2 * sizeof(*window):

|-------|-------|-------|-------|-------|-------|-------|-------
^               ^
window          buffer

which you then fread into

|-------|-------This i--|-------|-------|-------|-------|-------
^               ^
window          buffer

If you want to just point two bytes ahead, you have to add the 2 to a char*:

char* buffer = ((char*)window) + 2;

Upvotes: 2

user149341
user149341

Reputation:

You're getting tripped up by pointer math.

As window is declared as uint64_t *, window + 2 does not increment the address by two bytes; it increments it by 2 * sizeof(uint64_t) (that is, sixteen bytes). As a result, the memory you're looking at is uninitialized (and, in fact, lies outside the allocated block).

If you actually want the address to be incremented by two bytes, you'll need to cast the pointer to char * before adding 2 to it:

char *buffer = ((char *) window) + 2;

Upvotes: 6

Related Questions