简体   繁体   中英

Confusion about assigning value to a pointer with offset in C

I was manually assign integer value to a pointer with offset, it appears that ptr+1 was not actually pointed at second_int , or it was because the printf function didn't know the size of ptr+1 ?

#include <stdio.h>

int main(void)
{
    int first_int = 42;
    int second_int = 23;

    int *ptr = &first_int;
    *(ptr + 1) = second_int;

    int i = 0;
    for (i = 0; i < 2; i++) {
        printf("%d\n", *(ptr+i));
    }

    return 0;
}

And the output is:

42
1

Shouldn't it be 42 and 23?

And I found that each time I print the *(ptr+1) , it increments by 1.

#include <stdio.h>

int main(void)
{
    int first_int = 42;
    int second_int = 23;

    int *ptr = &first_int;
    *(ptr + 1) = second_int;

    int i = 0;
    for (i = 0; i < 10; i++) {
        printf("%d\n", *(ptr+1));
    }

    return 0;
}

And the output is:

0
1
2
3
4
5
6
7
8
9

What happened?

EDIT:
I'm only allowed to use pointer but not array (doing Learn C the Hard Way excercise). So I manually allocated memory for the ptr by int *ptr = malloc(sizeof(int) * 2); , then I assign value to ptr and ptr + 1 , and the code run as expected.

When you have a pointer to a single value, you're only allowed to dereference it to access that specific value, not other ones. To be able to increment a pointer it has to point to an object inside of an array.

Eg this would be valid:

int integers[2];
int *ptr = &integers[0];

*(ptr + 1) = 2; // Sets integers[1].

You seem to want set *(ptr + 1) to point at second_int . The only way you can make something point to a single value variable in C is to use the address operator, thus &second_int . But the type of that value is int* , not int . I think maybe what you wanted is something like this:

int first_int = 42;
int second_int = 23;

int *array[2];
array[0] = &first_int;
array[1] = &second_int;
int **ptr = &array[0];

Now you can use **ptr or *ptr[0] to access first_int , and **(ptr + 1) or *ptr[1] to access second_int .

In your code, ptr+1 is not memory managed by you.
It could be used by another program, or for any part or your program. What happens here is that the compiler optimizes away the second_int , as only its value is used. So no memory is allocated for it.
The next int in memory is fortunately also managed by you, and it is the index of your loop.
You thought memory layout was like this:
first_int | second_int | i

But it's like so:
first_int | i

If you want to be able to refer to both int with a pointer + offset, then you have to declare them as an array, to make sure that they are contiguous in memory:
int my_ints[2] = { 42, 0};
int *ptr = my_ints;
*(ptr+1) = second_int;
Then your code will work as intended.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM