# double pointer problem

• 04-29-2012
Z.K.
double pointer problem
Okay, well I am having some problems with double pointers. Now, I am hardly a programming expert and I would be the first to admit it. First off this is not homework. I can use a normal pointer okay and have had no problems doing this, but I have actually never used double pointers either in my programming classes when I was in college or in my job. I recently was asked about this though in a job interview even though the job never said anything about C or C++ expect for it would be nice to have C#. That's microsoft for you. I would like to understand this so in case I ever get asked this again.

Anyway I was given this below which I totally flubbed.

Code:

`void Reverse(char* str, char** rev)`
Since then about a week now I have tried to learn how to use the double pointer but have not had much luck. So, I thought maybe someone here could help me understand what I am doing wrong. I can get the same function with a normal pointer working find, but not using a double pointer. The code is below.

Oh, the function Reverse2 is what I am having trouble with.

:confused:

Code:

``` #include <iostream> #include <string> using namespace std; int strlen(char* str) {     int count = 0;     while( *str++ != '\0')     {             count++;     }     return count; } void Reverse(char* str, char* rev) {     int ptrcnt = 0;     ptrcnt = strlen(str)-1;     cout << "ptrcnt: " << ptrcnt << endl;     for(int i=ptrcnt; i >= 0; i--)     {         *(rev++) = *(str+i);     }     *rev = '\0'; } void Reverse2(char* str, char** rev) {     int ptrcnt = 0;     ptrcnt = strlen(str)-1;     cout << "ptrcnt: " << ptrcnt << endl;     for(int i=ptrcnt; i >= 0; i--)     {         **(rev++) = *(str+i);     }     **rev = '\0'; } int main() {     cout << "Hello world!" << endl;     char* string1 = new char;     char* string2 = new char;     char** string3 = new char*;     string3 = &string2;     cin.getline(string1, 80);     cout << string1 << endl << endl;     //Reverse(string1, string2);     //Reverse2(string1, string3);     Reverse2(string1, &string2);     cout << string1 << endl;     cout << string2 << endl;     delete string1;     delete string3;     delete string2;     return 0; }```
• 04-29-2012
oogabooga
Code:

```#include <iostream> #include <string> using namespace std; // Why would you write your own strlen function??? // I canned it. void Reverse2(char* str, char** rev) {     // I've moved the allocation of space into this routine since that makes     // more sense (otherwise why are you bothering to pass a double pointer?)     // Actually, it would make more sense to return the pointer but....     size_t len = strlen(str);     *rev = new char[len];     // If you're going to walk the given pointer through the array     // then you'd better make a copy of it (otherwise you'll alter the original).     char *p = *rev;     for(int i = len - 1; i >= 0; i--)         *p++ = str[i];     *p = '\0'; } int main() {     // Why are you only allocating one char of space???     char *string1 = new char[81];  // Need more that one char of space!!!     char *string2; // I moved allocation of this space into Reverse2 ... for fun.     cin.getline(string1, 80);     Reverse2(string1, &string2);     cout << string1 << endl;     cout << string2 << endl;     delete [] string1;     delete [] string2; }```
• 05-02-2012
Z.K.
Quote:

Originally Posted by oogabooga
Code:

```#include <iostream> #include <string> using namespace std; // Why would you write your own strlen function??? // I canned it. void Reverse2(char* str, char** rev) {     // I've moved the allocation of space into this routine since that makes     // more sense (otherwise why are you bothering to pass a double pointer?)     // Actually, it would make more sense to return the pointer but....     size_t len = strlen(str);     *rev = new char[len];     // If you're going to walk the given pointer through the array     // then you'd better make a copy of it (otherwise you'll alter the original).     char *p = *rev;     for(int i = len - 1; i >= 0; i--)         *p++ = str[i];     *p = '\0'; } int main() {     // Why are you only allocating one char of space???     char *string1 = new char[81];  // Need more that one char of space!!!     char *string2; // I moved allocation of this space into Reverse2 ... for fun.     cin.getline(string1, 80);     Reverse2(string1, &string2);     cout << string1 << endl;     cout << string2 << endl;     delete [] string1;     delete [] string2; }```

Thanks a lot. It has been awhile since I have used pointers. I was using C# for the last couple of years. Obviously I need to revisit pointers if I intend to do anything with C or C++. I made my own strlen because the C++ string library does not have it so I had to either make my own which was not difficult or include string.h. I had thought about the size when I was initially declaring string1, but the original version of Reverse without double pointers worked and it seems to work either way, but declaring it with
Code:

`new char[80]`
is probably the correct way. As to why use a double pointer in the first place, well that was the problem I was given and not my choice. Anyway, thanks.

This is my new modified function which now works :

Code:

```void Reverse2(char* str, char** rev) {     int len = strlen(str);     *rev = new char[len];     char *temp = *rev;     for(int i=len-1; i >= 0; i--)     {         *temp++ = *(str+i);     }     *temp = '\0'; }```
• 05-08-2012
dwks
Note that line 5 of your latest example should be
Code:

`    *rev = new char[len + 1];`
to add space for the NULL terminator, otherwise you have an off-by-one error. A buffer overrun. (Imagine a string of length 0 is passed in. Okay, you go new char[0], then the loop doesn't execute, but you still try to set *temp='\0'....)

As you've discovered, you have to be very careful about incrementing double pointers. If you have char **rev, which is pointing at some string char *p elsewhere, then **(rev++) really means to make rev point at the pointer following p in memory, which is probably not what you want (even undefined)... Your latest code essentially does *(*rev++), which makes more sense: follow rev to get to p, then post-increment p, and dereference p to get the character it points to. I know you've already figured it out, just thought an explanation of the syntax might be helpful. If you still have trouble then drawing the pointers out on a sheet of paper can be quite helpful! Cheers.
• 05-14-2012
brewbuck
In C, a double pointer usually indicates one of two things:

1. Somebody is passing a pointer "by reference." Using pointers is the only way to get reference-like parameter passing in C. If the thing you are passing is itself a pointer, the resulting thing is a pointer-to-pointer. This is the case in your string-reverse example.

2. Somebody is using an array of pointers.

Both of these cases should hopefully be easy enough to understand. So when you see a pointer-to-pointer, first figure out WHY it is being used, then it should become more clear. People don't (or at least shouldn't) be using them for no good reason.

I have, precisely once, seen a legitimate use of a triple pointer. And quadruple pointers and up are theoretical, as far as I'm concerned.