0

I have the following example code:

void doAlloc(int **p) {
  *p = (int *)malloc(sizeof(int));
  **p = 80;
}

int main() {
  int *ptr2;
  doAlloc(&ptr2);
  printf("%d\n", *ptr2);
  free(ptr2);
}

If I understand correctly, ptr2 is a pointer variable, and &ptr2 is "address of" that pointer variable in memory.

My question is, since doAlloc accepts a double pointer int **p as parameter; I don't understand why &ptr is a int **.

I would expect something like this to be done instead:

int **ptr2;
doAlloc(ptr2);

How is the "address of" ptr2 considered to be a valid value to pass as a double pointer?

Any help is greatly appreciated! Thanks.

  • because doAlloc gets a pointer to a pointer. A pointer itself - and not its value - is just like saying the address of. – Ariel Pinchover Nov 10 '13 at 20:59
  • its something usually done in C (to send address of) but i cant recall the reason, something with extra space – Ariel Pinchover Nov 10 '13 at 21:16
  • OT: In C it isn't necessary nor recommended to cast the results of `malloc/calloc/realloc`: http://stackoverflow.com/a/605858/694576 – alk Nov 10 '13 at 21:26

4 Answers4

0

&ptr2 is the address of ptr2.

Since pt2r is a pointer to an integer

&ptr2 is a pointer to a pointer to an integer:

int ** ptr2;

If it may help unserstandig the code above is equivalent to:

int  *doAlloc() {
  int *p;
  p = (int *)malloc(sizeof(int));
  *p = 80;
  return p; 
}

int main(void) {
  int *ptr2;
  ptr2 = doAlloc();
  printf("%d\n", *ptr2);
  free(ptr2);
}
alk
  • 69,737
  • 10
  • 105
  • 255
Paolo
  • 15,233
  • 27
  • 70
  • 91
0

A pointer is an address to a variable. The type of ptr2 is int * (pointer to int), i.e., it contains the address of an int. The argument of doAlloc is of type int ** (pointer to pointer to int), i.e., it contains the address of a pointer to int. Passing &ptr2 passes the address of ptr2, and since ptr2 is a pointer to int (int *), its address is of the correct type (int **).

(The reason why a pointer to pointer is required here is because doAlloc wants to modify the ptr2 pointer of main, not just the int it points to. A way to do it without the pointer to pointer would be to have doAlloc return a pointer to the allocated memory—then it would be the responsibility of the caller to assign it to a pointer.)

Arkku
  • 41,011
  • 10
  • 62
  • 84
  • Very helpful, thanks! Antonio's answer helped me figure it out conceptually, and now I understand your answer too. :) –  Nov 10 '13 at 21:29
0

Very simply, if you have

int a;

then

&a

Is of type int*

In your case, you have to consider an extra pointer for all your occurrences.

Antonio
  • 19,451
  • 13
  • 99
  • 197
0

A pointer in 'C' - yes - points to a memory location, where to store data (lets not talk about the type of, for now)

so let us assume: you do something like this (I try to go from the basics):

 int *p = 70;
 *p=65;

then you have your 'p' pointing to the address #70 (this is my syntax here for now thinking in 8-bit bytes no modern CPU architeckture), and then you assign '65' to where your 'p' points -> #70, so how looks the memory?

#6e ---
#6f ---
#70 65
#71 ---

so where is your 'p'?

#2212 --- here starts the stack
#2213 70 // p! 
#2214 --

and then you call: doAlloc(&ptr2);

that means: doAlloc get the address of 'p' ergo: 2213 and then it puts (a new alocated buffer address(!) there - into that 2213 - lets say '96'

#2212 --- here starts the stack
#2213 96 // p! new address of buffer 
#2213 --

and then you put '80' where this thing points to: 96 ... **p = 80;

#68 ---
#69 ---
#70 65
#71 ---
...
#94 ---
#95 ---
#96 80
#97 ---

I hope to point out what basicaly happens you could (theoretically) write

void doAlloc(int *p) {
  p = (int)malloc(sizeof(int));
  *p = 80;
}

so leave all the 2nd '*' alone

the compiler will tell you that it is wrong (and it is!), but that is what happens

halfbit
  • 3,773
  • 2
  • 34
  • 47