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

  1. #1
    Registered User
    Join Date
    Sep 2004
    Posts
    3

    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. #2
    Registered User
    Join Date
    Mar 2005
    Posts
    135
    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)
    Last edited by xeddiex; 04-22-2005 at 02:19 AM. Reason: took out header files

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > 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.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Using pointers to pointers
    By steve1_rm in forum C Programming
    Replies: 18
    Last Post: 05-29-2008, 05:59 AM
  2. function pointers
    By benhaldor in forum C Programming
    Replies: 4
    Last Post: 08-19-2007, 10:56 AM
  3. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  4. Staticly Bound Member Function Pointers
    By Polymorphic OOP in forum C++ Programming
    Replies: 29
    Last Post: 11-28-2002, 01:18 PM