Thread: double pointer problem

  1. #1
    Registered User
    Join Date
    Apr 2012
    Posts
    2

    Question 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.



    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;
    }

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    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;
    }
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  3. #3
    Registered User
    Join Date
    Apr 2012
    Posts
    2
    Quote Originally Posted by oogabooga View Post
    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';
    
    }

  4. #4
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    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.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  5. #5
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    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.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with double pointer
    By cjjoy1980 in forum C Programming
    Replies: 3
    Last Post: 01-08-2011, 02:44 AM
  2. Double liked list and double pointer
    By saillesh.sabari in forum C Programming
    Replies: 1
    Last Post: 12-10-2010, 11:03 AM
  3. Replies: 3
    Last Post: 10-30-2009, 04:41 PM
  4. double pointer problem
    By a0161 in forum C Programming
    Replies: 4
    Last Post: 05-10-2009, 07:52 AM
  5. Replies: 5
    Last Post: 04-04-2009, 03:45 AM