Use of char **

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • MatejSlansky
    New Member
    • Jan 2009
    • 1

    Use of char **

    Hi everybody,
    I'd like to ask for help with usage of char **. I have a following func, which dynamically allocates pointer a array

    and pointers of char[] arrays in it:

    Code:
    int sptr(char **ppchr)
    {
      int x = 0, ret = 0;
      char *pchr = NULL, **ptchr = NULL;
      
      // In place of for() you can imagine enumeration if something, quantity
      // of which is not known during design time. It's in extra func because
      // I'll need recursion (then I'll need extra parameter long *  for index
      // forward of course)
      for(x = 0; x < 10;x++)
      {
        // array of pointers allocation
        if((ptchr = (char **)realloc(ppchr, sizeof(char *) * (x + 1))) == NULL)
        {
          printf("ERR realloc\n");
          ret = 1;
          goto CleanExit;
        }
        ppchr = ptchr;
        // char[] allocation
        if((pchr = (char *)malloc(sizeof(char) * (11))) == NULL)
        {
          printf("ERR malloc\n");
          ret = 2;
          goto CleanExit;
        }
        memset(pchr, '\x0', sizeof(pchr));
        ppchr[x] = pchr;
        // fill out chararray
        sprintf(ppchr[x], "Item%d", x);
      }
    
    CleanExit:
      // freeing is only done if an error occurs, otherwise it manages
      // 'upper' procedure after it processes contents
      if(ret)
      {
        for(x = 0; x < 10;x++)
          if(ppchr[x])
          {
            free(ppchr[x]);
          }
        free(ppchr);
      }
      return ret;
    }
    And now where my problem is: as far as everything including contents processing is in one single procedure, everything goes like a charm, but I need from sptr() allocations and fill out and then to give that array to some func, which needs char ** as a parameter.

    So I moved declaration of **ppchr one level upper:

    Code:
    int main(int argc, char* argv[])
    {
      char **ppchr = NULL;
      int x = 0, ret = 0;
      
      ret = sptr(ppchr);
      
      printf("sptr ret: %d\n", ret);
      for(x = 0; x < 10;x++)
      {
        printf("Contents %d=%s\n", x, ppchr[x]);
      }
      
      if(!ret)
      {
        for(x = 0; x < 10;x++)
        if(ppchr[x])
        {
          free(ppchr[x]);
        }
        if(ppchr)
          free(ppchr);
      }
      return 0;
    }
    .. and sudenly everything goes wrong :-(. Or I have mistake in that declaration or in way of passing the array to sptr(), but I just never get that array back to main(), it almost looks like I'm passing this way something absolutely different :-). Notice that number nor size of char items is not known before run time and that I really need to pass it later as char **. So please don't advise use of struct, which is way I'd normally go in this case.

    Please explain what's wrong or how to make it work. I though that another way is not to pass initial char** pointer to sptr() and to return it instead (char **sptr(char *some_par()), however I just don't understand why the hell this doesn't work :-(

    Please don't advise vectors nor CString etc. I want to make it work in C, because I want to UNDERSTAND it, which usage of vectors doesn't give me.

    Thanks a lof for any help.

    Mates
  • newb16
    Contributor
    • Jul 2008
    • 687

    #2
    Add third '*' , like char *** ppchr; ... (*ppchr) = (char*) realloc( *ppchr, ... );
    and in main program call it like ... ( &ppchr)

    Comment

    • weaknessforcats
      Recognized Expert Expert
      • Mar 2007
      • 9214

      #3
      The argument ppchar is a COPY of the char** in main(). Any change to ppchar is a change to the COPY. The char** in main() is never altered.

      To do do this you need the address of the char** in main(). That means
      sptr() needs a char*** argument.

      What I would do is have sptr() return a void* and then typecast that void * into the correct pointer type.

      Comment

      Working...