-1

I'm struggling to create a pointer to pointer on the Heap. Here is my code:

double a = 2.289;

double** ptr = (double*) malloc(sizeof(double*));
double*** ptr_to_ptr = (double*) malloc(sizeof(double*));

I want the ptr variable to keep the address of a and ptr_to_prt the address of ptr. How can I then dereference the values. I want to do something like this:

printf("%lf", **ptr_to_ptr);

Thx in advance

  • `ptr` cannot both “keep the address of `a`” and hold the value returned by `malloc`. You could have `ptr` hold the value returned by `malloc` and `*ptr` hold the address of `a`. What do you want? – Eric Postpischil Oct 24 '20 at 14:53
  • 1
    Does this answer your question? [How do pointer to pointers work in C?](https://stackoverflow.com/questions/897366/how-do-pointer-to-pointers-work-in-c) – pradeexsu Oct 24 '20 at 15:05

2 Answers2

1

this show how to point and check addresses of pointer on the stack

#include <stdio.h>

int main(){
    double X = 2.25;
    double* pX = &X;
    double** ppX = &pX;

    printf("Addr X:   %8X\n", &X);
    printf("Addr pX:  %8X\n", &pX);
    printf("Addr ppX: %8X\n", &ppX);
    printf("Val X: %f", **ppX);
}

and this show how to point and show addresses on the heap

#include <stdio.h>
#include <stdlib.h>

int main(){
    double X = 2.25;
    double** pX = (double**) malloc(sizeof(double**));
    double*** ppX = (double***) malloc(sizeof(double***));

    *pX = &X;
    *ppX = &*pX;

    printf("Addr X:   %8X\n", &X);
    printf("Addr pX:  %8X\n", &*pX);
    printf("Addr ppX: %8X\n", &*ppX);
    printf("Val X: %f", ***ppX);
}

you will get a space from heap and store address in them so you need pointer to pointer just for save address of 'X'

Edit 1:

for better answer to comment i put code here

below code show use & operator

'&' operator just get address of variable, so *& get value of address that variable

now look at below code bot set value of x and both correct

#include <stdio.h>

int main(){
    int X;

    *&X = 10;
    printf("X: %d\n", X);

    X = 20;
    printf("X: %d\n", X);
}
Ali Mirghasemi
  • 462
  • 2
  • 7
  • 1
    `malloc(sizeof(double**))` allocates space for a `double **` but assigns it to a `double **`, which points to a `double *`. The C standard permits different types of pointers to be different sizes, so this is incorrect. Generally, when allocating space for some variable `pX`, it is better to specify the size using the variable, with `sizeof *pX`, rather than by using the type name. This both avoids errors like the above and automatically adjusts if the declaration of the variable is changed. – Eric Postpischil Oct 24 '20 at 15:02
  • it's almost right except better if we do *&ppX = &px. Anyway, a huge thanks for your help – STUDENTS PETROSCHOOL Oct 24 '20 at 15:41
  • can anybody explain please why *&ppX = &px works, but *ppX = &px does not? – STUDENTS PETROSCHOOL Oct 24 '20 at 16:04
  • first you must know what is this '&' operator and what is does, '&' operator get address of a variable so when you use &x you get address of where x is stored, now when you use *&x you get value of address of 'x', now look at this int x; *&x = 10; // same as this x = 10; – Ali Mirghasemi Oct 24 '20 at 16:09
  • but it still not clear for me why is *ppX = &px does not work in this case – STUDENTS PETROSCHOOL Oct 24 '20 at 16:14
  • Because type of &*px is double* and &px is double**, so they type are not same – Ali Mirghasemi Oct 24 '20 at 16:37
0

You need an extra asterisk to have the correct type:

double a = 2.289;
double** ptr = (double**) malloc(sizeof(double*));
double*** ptr_to_ptr = (double***) malloc(sizeof(double**));

To dereference you will need as many asterisks as the amount of levels you want to go down. See the example:

int x = 5;
int *p = &x;
int **p2 = &p;

printf("%p %p\n",*p2, p); //If you use 1 asterisk you get to p
printf("%d", **p2); // If you use 2 asterisks you get what p points to, which is an int in this case
 
vmp
  • 2,370
  • 1
  • 13
  • 17
  • Casting to `double *` for assignment to `double **` is incorrect. The proper type for `double **` is of course `double **`. Similarly for `double ***`. Additionally, it is generally better to use `sizeof *ptr` when allocating for `ptr`, rather than `sizeof(some type)`, as the former avoids errors in matching the type to the object being allocated and automatically adjusts when the declaration of the pointer is changed. – Eric Postpischil Oct 24 '20 at 14:46
  • but how to assign the address of ptr to ptr_to_ptr? – STUDENTS PETROSCHOOL Oct 24 '20 at 14:51