6 Replies - 1016 Views - Last Post: 15 January 2013 - 06:59 PM Rate Topic: -----

#1 EXCELL3NCE  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 10-January 13

Pointer to Pointer The double asterisks need or not needed?

Posted 11 January 2013 - 12:51 PM

So my question pretains to pointers to a pointer. I've been working with passing array data structures and other data structures to my functions. This reminded me of something I read a while back in one of my first C++ tutorials.

Anyways, is it honestly necessary to declare a pointer thats meant to point to another pointer with the double asterisks?

int **pointer


Also is what if, lets say we are passing different variables to a function whose function parameters contains a pointer.

void functionExample(int *ptr){~}

int main(){

int a, b;
int *c;

functionExample(&a);
functionExample(&c);  //Pointer to Pointer



So would this cause problems? Since its a pointer to pointer with the receiving pointer being declared with only 1 asterisks.

Is This A Good Question/Topic? 0
  • +

Replies To: Pointer to Pointer The double asterisks need or not needed?

#2 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2153
  • View blog
  • Posts: 3,315
  • Joined: 21-June 11

Re: Pointer to Pointer The double asterisks need or not needed?

Posted 11 January 2013 - 01:42 PM

Yes, it's a problem. Your code will fail to compile with an error message telling you that there's no implicit conversion from int** to int*.

You can make it compile without changing the types of the variables by adding a cast, but more likely than not that will lead to undefined behavior (depending on what exactly your function does with the pointer - if it doesn't do anything with it, there won't be UB).
Was This Post Helpful? 0
  • +
  • -

#3 mojo666  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 356
  • View blog
  • Posts: 785
  • Joined: 27-June 09

Re: Pointer to Pointer The double asterisks need or not needed?

Posted 11 January 2013 - 01:46 PM

View PostEXCELL3NCE, on 11 January 2013 - 07:51 PM, said:

Anyways, is it honestly necessary to declare a pointer thats meant to point to another pointer with the double asterisks?

int **pointer


It has its uses. Multi-dimensional arrays is one use that comes to mind.

Quote

Also is what if, lets say we are passing different variables to a function whose function parameters contains a pointer.

void functionExample(int *ptr){~}

int main(){

int a, b;
int *c;

functionExample(&a);
functionExample(&c);  //Pointer to Pointer



So would this cause problems? Since its a pointer to pointer with the receiving pointer being declared with only 1 asterisks.

Best case scenario, the compiler crashes due to incorrect type matching. Worst case scenario, the program runs and causes a memory leak. I don't think it will compile.
Was This Post Helpful? 0
  • +
  • -

#4 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3662
  • View blog
  • Posts: 11,481
  • Joined: 05-May 12

Re: Pointer to Pointer The double asterisks need or not needed?

Posted 11 January 2013 - 01:58 PM

And traditional C programmers migrating to C++ will typically write something like this:
void AllocateXYZ(X **px, Y **py, Z **pz)
{
    *px = new X;
    *py = new Y;
    *pz = new Z;
}



instead of
void AllocateXYZ(X *&x, Y *&y, Z *&z)
{
    x = new X;
    y = new Y;
    z = new Z;
}


Was This Post Helpful? 1
  • +
  • -

#5 jimblumberg  Icon User is offline

  • member icon


Reputation: 4288
  • View blog
  • Posts: 13,453
  • Joined: 25-December 09

Re: Pointer to Pointer The double asterisks need or not needed?

Posted 11 January 2013 - 02:07 PM

Quote

Anyways, is it honestly necessary to declare a pointer thats meant to point to another pointer with the double asterisks?

Sometimes, yes it is necassary.

Quote

So would this cause problems? Since its a pointer to pointer with the receiving pointer being declared with only 1 asterisks.

In your example: functionExample(&a); would not be a problem since a is an int.
However: functionExample(&c); would cause a problem since c is already a pointer.

Your compiler should be able to tell you about these problems, did you try compiling those examples?

When I compiled the following code:
void functionExample(int *ptr);

int main() {

	int a, b;
	int *c;

	functionExample(&a);
	functionExample(&c);  //Pointer to Pointer

}

void functionExample(int *ptr)
{

}



My compiler issued these warnings and errors:

Quote

main.cpp||In function ‘int main()’:|
main.cpp|9|error: cannot convert ‘int**’ to ‘int*’ for argument ‘1’ to ‘void functionExample(int*)’|
main.cpp|5|warning: unused variable ‘b’ [-Wunused-variable]|
main.cpp|13|warning: unused parameter ‘ptr’ [-Wunused-parameter]|
||=== Build finished: 1 errors, 2 warnings ===|


Many times experimenting will teach you many things. One of these things is possibly how to interpit your compiler error and warning messages.

Jim
Was This Post Helpful? 0
  • +
  • -

#6 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: Pointer to Pointer The double asterisks need or not needed?

Posted 11 January 2013 - 05:11 PM

A pointer to a pointer is called "double indirection" and as the name seems to imply it can be difficult to really wrap your head around.

Generally think of it just as a pointer... that just happens to point to another pointer.

Lets go back to old C programming for a bit. Lets say that I was working on the infamous 99 bottles of beer problem and wanted a function that returned either "bottles" or "bottle" depending upon an argument.

#include <stdio.h>

const char* const singleBottle = "bottle";
const char* const multipleBottles = "bottles";
const char* const line1 = "%d %s of beer on the wall; %d %s of beer;\n"
                    "   Take one down, pass it arround...\n";
const char* const line2 = "   %d %s of beer on the wall!!!\n";
            

void chooseCorrectText(int count, const char** text) {
    if (count == 1) {
        *text = singleBottle;
    } else {
        *text = multipleBottles;
    }
}

void takeOneDown(int* pCount) {
    (*pCount)--;
}

int main() {
    int i = 5;
    const char* bottleptr;
    while(i > 0) {
        chooseCorrectText(i, &bottleptr);
        printf(line1, i, bottleptr, i, bottleptr);
        takeOneDown(&i);
        chooseCorrectText(i, &bottleptr);
        printf(line2, i, bottleptr);
    }
    return 0;
}

Now the above would have been confusing to me for the first few years I was programming C so lets see if we can walk though it.

#1 lets clear this up: const char* bottleptr; pointer declarations are read backwards so we have "bottleptr is a POINTER to a CHAR CONSTANT" - That is bottleptr is mutable (non-constant), but what it points to is not.

(as opposed to const char* const singleBottle = "bottle"; which says: "singleBottle is a CONSTANT pointer to a char constant" - so singleBottle can not be changed.

So lets take this from a bottom up approach. In the line:
printf(line1, i, bottleptr, i, bottleptr); we want the pointer variable bottleptr to contain the address of either "bottles" or "bottle".

So we pass bottleptr BY REFERENCE to chooseCorrectText(int count, const char** text): So text is a pointer to the bottleptr (which happens to be a pointer). so *text gets us to bottleptr which is what we want to change:
*text = singleBottle;
so now we have assigned bottleptr to the value of singleBottle. so bottleptr now points to the string "bottle" in memory.

I made the function takeOneDown to demonstrate that concepts of pass by reference when the value is not a pointer. The pointer pCount points to some integer that holds our count, so *pCount gives us access to that value and (*pCount)-- will decrease that value by 1.


All of this is maybe a little easier to see when we look at a generic function in C++ like swap written out in C.
template<typename T>
void swap(T* v1, T* v2) {
    T temp = *v1;
    *v1 = *v2;
    *v2 = temp;
}
when you simulate this for ints in C you get:
void c_swap_int(int* v1, int* v2) {
    int temp = *v1;
    *v1 = *v2;
    *v2 = temp;    
}


When you simulate this for int* (say you want to swap two arrays) in C you get:
void c_swap_int(int** v1, int** v2) {
    int *temp = *v1;
    *v1 = *v2;
    *v2 = temp;    
}


This will swap two pointers. Say you wanted to swap two 2D arrays:
void c_swap_int(int*** v1, int*** v2) {
    int **temp = *v1;
    *v1 = *v2;
    *v2 = temp;    
}


So you see a pattern forming? the algorithm is the same - the only thing that needs to change is the datatype of what we are swapping.
Was This Post Helpful? 0
  • +
  • -

#7 jjl  Icon User is offline

  • Engineer
  • member icon

Reputation: 1112
  • View blog
  • Posts: 4,619
  • Joined: 09-June 09

Re: Pointer to Pointer The double asterisks need or not needed?

Posted 15 January 2013 - 06:59 PM

The logic between double, triple, or N pointers is no different from a single pointer.

When you declare a "non-void" pointer, you specify a target type (the type the pointer is pointing to).

example of a single pointer
int x = 10;
int *y = &x; //target type is int



The pointer y is declared to point to a target type of int. Therefore, when assigning the pointer address, you specify the address of an int

example of double pointer
int x = 10;
int *y = &x; //single pointer, target type is int
int **z = &y; //double pointer, target type is int pointer



The variable z is declared with a target type of int pointer, that implies that z can only point to type int pointer.

If you follow this logic to N pointer indirections, you will see that a pointers target type is defined by the type before the last asterisk in it's definition.

example of N pointer
int *a; //target type is (int)
int **b; //target type is (int*)
int ***c; //target type is (int**)
int ****d; //target type is (int***)
...


This post has been edited by jjl: 15 January 2013 - 06:59 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1