2

Well, I think it may be a stupid question, but I want to know how this code works.

Here is an example code.

typedef struct {
    int first;
    int second;
    int third;
}mypointer;

int main()
{
    mypointer *mp = 0;
    printf("this is third member : %p\n", &mp->third);

    return 0;
}

I guess it should return segmentation fault, because pointer mp points to zero address and points to invalid memory address. However, actual result is different.

this is third member : 00000008

I know, it is bad, but it works.

So, I guess that when I points to struct member whatever struct is allocated or not, I am able to get address of struct member.

Is this correct?

Sujin Lee
  • 23
  • 3
  • Why you want to get address of struct member which points to zero address without normal initialization? – JimmyHu Mar 17 '20 at 13:12
  • 2
    @JimmyHu Look at a few implementations of `offsetof()`. **Why** this works is actually a very interesting question. – Andrew Henle Mar 17 '20 at 13:16
  • `sizeof(int) = 4`. It does: `mov QWORD PTR [rbp-8], 0` so you can see it initializes the pointer to 0. Then it does `mov rax, QWORD PTR [rbp-8]`.. which stores the pointer in rax. Now it does `add rax, 8` (two ints).. so technically, it's never actually dereferencing the pointer. – Brandon Mar 17 '20 at 13:41
  • The pointer invalid, but it is never dereferenced. It's perfectly legal to have invalid pointers (NULL is one of them) as long as you don't dereference them and you code doesn't. – Jabberwocky Mar 17 '20 at 13:43
  • @JimmyHu I have seen codes similar to ```offsetof()```, but I don't know what exactly code means. @AndrewHenle Thanks, ```offsetof()``` is a good explanation about my example code. – Sujin Lee Mar 17 '20 at 15:32
  • @Jabberwocky What I understand from your comment is that invalid pointer without dereferencing is legal. Thanks. – Sujin Lee Mar 17 '20 at 15:40

1 Answers1

2

you initialized mypointer *mp = 0.

As you point head of this pointer to zero address:

address ofmp->first is &mp->first=00000000 as you initialized it .Then for mp->second (the way pointers arithmetic works) it will point to a address of mp->first + sizeof(int) then for
mp->third address will be address of mp->first + sizeof(int) + sizeof(int).

let suppose that int is 4 byte in your system so &mp->third=00000000+4+4

which is equal to 00000008

But yet you can't access memory because of head pointing to NULL.

hanie
  • 1,863
  • 3
  • 9
  • 19