1

When researching double pointers, the general consensus appears to be when wanting to change the value of any variable and retain the new value when returning from a function then its pointer value needs to be passed in.

When already working with a pointer then a double pointer needs to be passed in.

The following example deals with a pointer in the main portion of the code, passes that same pointer to a function, changes its value and the new value is visible in main.

Based on what I read, a double pointer should have been required or else the new value would not be visible within main.

If this does work, then how could it be modified to show that a double pointer is required?

void func1(int *z)
{
(*z)++;
printf("z=%d\n", *z);
}   


int _tmain(int argc, _TCHAR* argv[])
{

int x = 100;
int *y = &x;
printf("y=%d\n", *y);
func1(y);
printf("y=%d\n", *y);
return 0;
}
Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
Unhandled Exception
  • 1,427
  • 14
  • 30
  • You're passing the address of an int, and then incrementing the value at that address. Why would a "double pointer", as you say, be required? – wickstopher May 20 '14 at 02:19
  • This question is extremely confusing. "Double pointers" or pointers to pointers are seldom needed. Habitual use is a sign of disorganization. The first sentence of this question needs to be broken into two or three parts if it is to be coherent. Why would you ever need to seek a proof that additional complexity is necessary, in something that already works? – Potatoswatter May 20 '14 at 02:39
  • Consult http://stackoverflow.com/questions/897366/how-do-pointer-to-pointers-work-in-c/897414#897414 and http://stackoverflow.com/questions/15151377/what-exactly-is-a-c-pointer-if-not-a-memory-address – 9dan May 20 '14 at 02:49
  • if you want to pass something to a function to be modified, you need to pass a pointer to it. if you want it to modify an `int`, you need an `int*`. If you want to modify an `int*` you need an `int**`. `y` has type `int*` which allows you to indirectly modify an `int` (`x` in this case) – Ryan Haining May 20 '14 at 03:08

5 Answers5

3

You'd need a pointer to a pointer if you were changing what y is pointing to, so for example :-

static int blah = 42;
void func1(int **z)
{
(*z) = &blah;
printf("z=%d\n", *(*z));
}   

int _tmain(int argc, _TCHAR* argv[])
{

int x = 100;
int *y = &x;
printf("y=%d\n", *y);
func1(&y);
// y does not point to x anymore;
printf("y=%d\n", *y);
return 0;
}

in your original you were changing x, in this you are leaving x alone and changing the pointer y.

Typically you don't use these that much ( you do use them from time to time) but more generally your pointer to a pointer is a more interesting type.

so...

typedef struct 
{
   int *y;
} Z;

void f(Z *z)
{
  z->y = &blah;
}

void main()
{
  int x;
  Z a;
  a->y = &x;
  f(&a);
}

so this effectively the same thing, but now you're using a struct to hold the pointer, and you pass the pointer of the struct around as a "pointer to a pointer" except now its a pointer to a struct which contains a pointer to an int.

But you name things a bit more interestingly :-

typedef struct 
{
  char *name;    
} Person;

static char* default_name = "blah";
void set_default_name_of_person(Person* person)
{
   person->name = default_name;
}

void main()
{
   Person person;
   set_default_name_of_person(&person);
}

and now your code is starting to look like something you'd actually write. (other than this being a bit of a contrived example )

Keith Nicholas
  • 43,549
  • 15
  • 93
  • 156
  • #include void func1(int *z) { int k=11; //(*z)++; *z=k; printf("z=%d\n", *z); } int main (int argc, char* argv[]) { int x = 100; int *y = &x; printf("y=%d\n", *y); func1(y); printf("y=%d\n", *y); return 0; } – Mukul Mehra Feb 24 '22 at 19:19
0

Firstly - saying "pointer to pointer" is more clear, as "double pointer" could be double *.

Suppose T is some type, and you have:

T t;
func( &t );

For func to be able to change t, it must know the address of t. The address of an object is a pointer to that object (that's the definition of the term pointer).

So the function signature must be:

func( T *t_ptr )

In your example T is int. Perhaps you are getting mixed up with examples where T is already a pointer type. There's nothing "magic" about pointer types. int * and int ** and int *** are types, just like int. The same rules apply to all of them.

If T is int *, then the function signature must look like func( int **t_ptr_ptr ), and so on.

M.M
  • 138,810
  • 21
  • 208
  • 365
0

Pointer is simple. Just think it as a kind of address.

There is a box. This box has a number plate which says 1-101.

The box is the variable, the number plate is the pointer, and 1-101 is the actual address (abstract concept).

I can give you the box and you can fill it with papers, but also I only can show you the number plate and you could reach the box and fill it.

Suppose there is a number plate with 'pp1-100', you located the plate holder but it is another number plate with 'p1-100'. You again locate the holder and could find the box.

This is the 'pointer to pointer'.


Why we need double/triple/quadruple pointers? Because we want it, in various reasons (but who cares?).

9dan
  • 4,222
  • 2
  • 29
  • 44
0

If address of local variable is assigned to the single pointer it would still work. So the opening statement from Keith Nicholas makes a lot of sense and should be accepted as a valid answer. If you need to change the value in original address you need a single pointer but if you are changing the value by changing the location itself then a pointer to pointer is needed. You should understand that you are passing the pointer by value so the function stack has a copy of that pointer variable(and its value). By dereferencing the copy of main's pointer variable the value of original variable changes because it is a copy of original variable's address. But if you point that ponter's copy to a different value it will not get reflected. Run below code by uncommenting 1 and 2 (one at a time) to observe the difference. Observe what happens to the original variable x

#include <stdio.h>
void func1(int *z)
{
    int k=11;

//*z=k;   //1
//z=&k;    //2
printf("z=%d\n", *z);
}   


int main (int argc, char* argv[])
{

int x = 100;
int *y = &x;
printf("y=%d\n", *y);
func1(y);
printf("y=%d\n", *y);
printf ("%d",x);
return 0;
}
Mukul Mehra
  • 91
  • 1
  • 9
-1

You've used the function to change the value of x, otherwise known as *y.

The code snippets that you've seen are not attempting to change the value of x, but are in fact changing the value of y so that y points to something different after the function call. In order for the function to change the value of y, it needs a pointer to y. Since y is already a pointer, you end up with a pointer to a pointer.

Here's your code rewritten to change what y points to, so that after the function call, y points to w and the printf displays 333.

void func1( int **yptr, int *wptr )
{
    *yptr = wptr;
}

int main( void )
{
    int x = 100;
    int w = 333;

    int *y = &x;
    func1( &y, &w );
    printf( "*y=%d\n", *y );

    return 0;
}
user3386109
  • 34,287
  • 7
  • 49
  • 68