I’m learning C and now I hit a wall. Its difficult for me to understand pointers.
Imagine I have this code:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define DELTA 33
int calls, seed=356;
int sum_ds(int a){
int d=DELTA;
calls++;
return a+d+seed;
}
int main() {
int num;
int *ptr;
int **handle;
num = 14;
ptr = (int *)malloc(2 * sizeof(int));
handle = &ptr;
*(*handle+0) = num;
*(*handle+1) = num+1;
*ptr = num-2;
ptr = #
*ptr = sum_ds(num-2);
}
Lets go step by step trough my understanding.
1 – int calls creates a variable named calls and doesn’t initializes it so it contains rubbish. It is stored on DATA and let’s say with the memory address 0xFFAA.
2 – int seeds creates a variable named seeds initialized with the integer 356. It is stored on DATA and let’s say with the memory address 0xFFAB.
3 – int num creates a variable named num and doesn’t initializes it so it contains rubbish. It is stored on the STACK and let’s say with the memory address 0xFFAC.
4 – int *ptr creates a pointer to int and does not assign any address to it. It is stored on the STACK and let’s say with the memory address 0xFFAD.
5 – int **handle creates a pointer to a pointer of int and does not assign any address to it. It is stored on the STACK and let’s say with the memory address 0xFFAE. (MANY DOUBTS HERE)
6 – num = 14 goes to the address 0xFFAC and stores the number 14 on it. It’s done in the STACK.
7 – ptr = (int *)malloc(2 * sizeof(int)) On the HEAP it’s assigned memory size for 2 ints and the address of the first memory byte (let’s say 0xFFZZ) is stored (on STACK) on ptr so now *ptr points to that memory address.
8 – handle = &ptr handle now points to ptr. I believe it now points to whatever is on 0xFFZZ (MANY DOUBTS HERE)
9 – *(*handle+0) = num the pointer to the pointer of int now its assigned with the value of num (14) (MANY MANY MANY MANY DOUBTS HERE)
10 – *(*handle+1) = num+1 the pointer of pointer plus one of int now its assigned with the value of num + 1 (15) (MANY MANY MANY MANY DOUBTS HERE)
11 – *ptr = num-2 the value point by ptr it’s assigned with the value of num – 2 (12). I believe it goes to the memory address 0xFFZZ and stores there the number 12.
12 – ptr = &num ptr now points to num, i believe it now points to 0xFFAC.
13 – *ptr = sum_ds(num-2) the value pointed by ptr is the returned value of sum_ds. I belive 0xFFAC it’s assigned with 401 (12+33+356)
Is this right?
One little detail:
sizeof(int)is greater than 1 (it is 4 on most mainstream platforms, so the 2nd address could not be 1 higher than the 1st. Other than that, AFAIK you are correct so far.Another little detail: on most mainstream platforms, the stack grows downward, so the 4th address would be less than the 3rd. Other than that, AFAIK you are correct so far. (Moreover, addresses on the data segment, the heap and the stack would be rather different in real life.)
To be nitpicky, ‘Z’ is not a hexadecimal number 🙂 So let’s say it is
0x1000instead.No,
handlenow contains the address ofptr, that is0xFFAD. Indirectly though – throughptr– it indeed points to0x1000(was0xFFZZin your example).Basically correct. The notation you use is not the easiest to deal with, which makes it more difficult for you to follow what’s going on. After step 8,
*handleis equivalent toptr. And due to pointers and arrays being interchangeable in many common situations, *(ptr+0) is equivalent toptr[0], and also to*ptr.Similar to the previous point, you are in effect assigning
ptr[1] = num+1. Keep in mind though thatptrisint*, so the address difference betweenptrandptr + 1equals tosizeof(int), which is, as mentioned above, usually 4.Yes, this overwrites the value set in step 9.
Correct.
Correct. Since the previous step made
*ptrequivalent tonum, this call is also equivalent tonum = sum_ds(num-2).