# Thread: pointers to pointers (**a, for example)

1. ## pointers to pointers (**a, for example)

I have a simple question regarding pointers of the form **a. I have been trying to incorporate some external code into a program of mine, and one of the functions takes on a pointer like this as an argument. Furthermore, when the thing is used in the function, it is referred to as a two dimensional array. This is confusing to me, since I'm new to C. I'm looking for conceptual help here.

I've got the thing copied in properly, I think, but I don't know what preceisely to put in this argument slot. I've tried putting in the array, a pointer to the array, and a pointer to the pointer to the array. Everything either won't compile, or calling the function yields a segmentation fault.

I'm including the code, assuming that might help clarify things a bit. It's the first phase of a two part algorithm to get the eigenvalues and eigenvectors of a real symmetric matrix. This thing puts the matrix in a special form (tri-diagonal form) via similarity transforms.

Thanks!

Code:
```void tred2(int n, double **a, double d[], double e[]){
int l,k,j,i;
float scale, hh, h, g, f;

for (i=n; i>=2; i--){
l=i-1;
h=scale=0.0;
if(l>1){
for(k=1;k<=l;k++)
scale +=fabs(a[i][k]);
if(scale == 0.0)
e[i]=a[i][l];
else{
for(k=1;k<=l;k++){
a[i][k] /= scale;
h += a[i][k]*a[i][k];
}
f=a[i][l];
g = (f >= 0.0 ? -sqrt(h) : sqrt(h));
e[i]=scale*g;
h -= f*g;
a[i][l]=f-g;
f=0.0;
for(j=1; j<=l; j++){
a[j][i]=a[i][j]/h;
g=0.0;
for(k=1;k<=j;k++)
g += a[j][k]*a[i][k];
for(k=j+1;k<=l;k++)
g += a[k][j]*a[i][k];
e[j]=g/h;
f += e[j]*a[i][j];
}
hh=f/(h+h);
for(j=1;j<=1;j++){
f=a[i][j];
e[j]=g=e[j]-hh*f;
for(k=1;k<=j;k++)
a[j][k] -= (f*e[k]+g*a[i][k]);
}
}
} else
e[i]=a[i][j];
d[i]=h;
}
d[1]=0.0;
e[1]=0.0;

for(i=1;i<=n;i++){
l=i-1;
if(d[i]){
for (j=1; j<=1; j++){
g=0.0;
for(k=1;k<=l;k++)
g += a[i][k]*a[k][j];
for(k=1;k<=l;k++)
a[k][j] -= g*a[k][i];
}
}
d[i]=a[i][i];
a[i][i]=1.0;
for(j=1;j<=l;j++)
a[j][i]=a[i][j]=0.0;
}
}```

2. Alright, I'm not that good at explaining things but I'll try my best to do it - carefully, easily and detailedly.

char szarr[5];
char *ptr = szarr;

char **p2p; // pointer to pointer (It can only hold and point to the address of a pointer)
p2p = &ptr; // assigns the address of the pointer ptr to p2p.

assign characters in string "car" to szarr array
via pointer, ptr; and finally prints "car":
puts(strcpy(ptr, "car"));

Say you want to modify the array (szarr) ptr points to via p2p;
You would do this by doing this in the following steps:

1. p2p alone, yields the address of ptr because we assigned ptr's address to it, remember?
.. and, we want to work with the array and not the pointer so..

2. p2p[0].. (fetches the address p2p points to and adds 0, which also can be done with pointers instead:
*(p2p + 0)) ..yields what ptr is pointing to, which is the array szarr we assigned to it.

3. now that we have szarr to work with after doing the above step, you can use p2p[0] or *(p2p + 0) just like
... if you were directly using szarr. (example: gets(*(p2p + 0)) == gets(szarr)) But how do we change
... a character value within the array szarr via *p2p? Like this:

4. Let's change the last character in the string; p2p[0][2] = 't' or *(*(p2p + 0) + 2) = 't';
.. What did we just do?. We already know how p2p[0] works but how does the second subscript work?
.. Remember p2p[0] is like using szarr directly? well, what happens if we do p2p[0][2]? we access a charcter
.. value within the array for read or write purposes. so since p2p[0] is (again) like using szarr directly
.. (it's really indirectly because anytime you work with pointers, it's done indirectly) you can do p2p[0][2].
.. p2p[0] is like replcaing it with szarr and then you just add the [2]... szarr[2] which is equivelant to doing p2p[0][2];.

p2p[0][2] = 't';
Or, using pointer notation: *(*(p2p + 0) + 2) = 't';

puts(ptr);
prints "cat"

Note: p2p + 0 is not really necessary in this example because *(*(p2p) + 2) alone references ptr,
but I included it (+ 0) for the sake of better understaning this example and also note, going beyond + 0 is deffinetly NOT good!
as we would be accessing memory that is not ours (part of our program)

3. > void tred2(int n, double **a, double d[], double e[])
Well if you tried to pass an array (say double results[10][20]), then that would be very wrong.

If you have an array (like my example), then the array parameter would be declared like this
void tred2(int n, double (*a)[20], double d[], double e[])

Next time, show the context in which you call the function, and pay particular attention to how variables are declared, especially arrays and pointers.