Thread: dereferencing char pointer array

  1. #1
    Registered User
    Join Date
    Mar 2006
    Posts
    5

    dereferencing char pointer array

    newbie here (be gentle !)
    I've got a call to a function that does some parsing. It supposedly returns a pointer to an array of char pointers. How does the calling program dereference the pointers to place the references into a character array ?

    Here are the implementation details of the function:
    char **foo(const char *inputString, const char *theDelims)
    static char *Token[MAXSYMBOLS];
    return Token

    I've got these declarations in the calling program

    char g_symbols[MAXSYMBOLS];
    char **g_symbol;

    and this call:

    g_symbol = foo("xxxxx,yyyyy", ",")

    Now what do I do to place the return result into g_symbols ?
    TIA.

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    If I get this right, you want to return an array of pointers to a function, and further, you want this function which takes the return to be able to modify the array (which is static)?
    This sounds awfully complicated and some work-around issue.
    Why not explain what you're trying to do?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If the function returns char **bob, then *bob is a pointer to char. (If you want to/are supposed to interpret this as an array of char *, you can write "bob[0]" for *bob.) You can then strcpy that from bob[0] to g_symbols[0]. Increment index, lather, and repeat.

  4. #4
    Registered User
    Join Date
    Nov 2003
    Posts
    161
    One thing that doesn't seem to make sense is the following 2 declarations:

    Code:
    static char *Token[MAXSYMBOLS]; 
    ...
    char g_symbols[MAXSYMBOLS];
    As it appears to me you are using MAXSYMBOLS size for both (Amount of Tokens & Token size). Token is an array of pointers, and g_symbols is an array of char's which is likely to be a string. You might want a new size saying the maximum size of a token.

    For example: you can have a maximum symbols of say 5 (maybe parsing a string 5 bits at a time). But a token could be a length of 6 which is more than 5. Now you will have a buffer overflow.

    Similarly for large numbers: if you have MAXSYMBOLS as 200, memory will probably be wasted as token sizes would be ~20chars.

  5. #5
    uint64_t...think positive xuftugulus's Avatar
    Join Date
    Feb 2008
    Location
    Pacem
    Posts
    355

    Post

    Code:
    static char *Token[MAXSYMBOLS]; 
    ...
    char g_symbols[MAXSYMBOLS];
    It looks like the function is returning a set of string starts that should be assigned differently to the g_symbols variable. In C a string, a true string is character array allocated either statically or dynamically to which we know the start and that at some point has a special character '\0' to mark it's end. When a function returns an array of string starts, based on a given true string, like in this example, it returns merely something equivalent to page-markers in a book. But someone who needs to study the things the page-markers show would go to get a printed copy of all the "marked" pages. Every Token[i] is the same as a page-marker.
    g_symbol, is just a set of page-markers.
    g_symbols, is an array of characters, or in other words a fixed width page.
    To store the return value of foo() it would be necessary to get some blank pages and get a copy of the contents that the page-markers foo() returns indicate.
    char g_symbols[MAXSYMBOLS], is not a good type to do that.
    The best would be either:
    Code:
    char g_symbols[MAXSYMBOLS][MAXSYMBOLSIZE];
    //or
    char *g_symbols[MAX_SYMBOLS];
    On the first one could get hard copies by saying using strcpy() with target every g_symbols[i] and source every g_symbol[i]. The problem is that if a g_symbol[i] has more length than our MAXSYMBOLSIZE constant, we would get overflow and corrupted data.
    On the second, one could either malloc() every g_symbols[i] to the appropriate string length()+1 for the ending '\0'. or use a more elegant in my opinion call to strdup(), like:
    Code:
    // Case 1
    ...
    strcpy(g_symbols[i], g_symbol[i]);   /* Buffer overflow danger */
    ...
    // Case 2 solution 1
    g_symbols[i] = malloc(strlen(g_symbol[i]) + 1);
    strcpy(g_symbols[i], g_symbol[i]);    /* Ok, memory is enough and never fails */
    ...
    // Case 2 solution 2, notice how much it looks like case 1.
    g_symbols[i] = strdup(g_symbol[i]);   /* Guaranteed to work if we have memory */
    So, it comes down that duplicating an array of string is as simple as to repeat a simple operation. The only things that needs to be correct to use this elegant and safe 99.99% of the time solution, is the type of an array of string starts, which is: char *str_array[N].
    The memory allocation management is "handled" by strdup, and the programmer need release the pointers himself afterwards. That simple.
    Last edited by xuftugulus; 02-18-2008 at 02:52 PM.
    Code:
    ...
        goto johny_walker_red_label;
    johny_walker_blue_label: exit(-149$);
    johny_walker_red_label : exit( -22$);
    A typical example of ...cheap programming practices.

  6. #6
    Registered User
    Join Date
    Mar 2006
    Posts
    5

    Thanks all...

    wow, this group is sharp.
    I want to especially thank xuftugulus as he really hit it "on the mark" and his explanation of "string starts" was just what I was looking for.

    I've got a programming background, but it's always been "high-level" with either scripting languages, VB, or VBA. "C" has always mystified me, but I've got a current project that requires me to build a DLL "wrapper" from a bunch of C functions and libraries to be accessed from Excel.

  7. #7
    Registered User
    Join Date
    Mar 2006
    Posts
    5
    Unfortunately, nothing worked here.
    The closest I came was getting the first string starter back.
    I want a static approach as none of the strings will ever exceed 4 characters.

    char **g_symbols[MAXSYMBOLS][5] // note: strings will be a max of 4 characters wide

    **g_symbols = foo("xxxxx,yyyyy", ",") // only returned xxxxxx

    returned my first token, but that was it.
    Somehow, the declaration in the calling program is wrong.

    I was reading about multidimensional arrays and wondering
    if I need to use a pointer like this:
    char (*ptr)[MAXSYMBOLS]

    Under no circumstances show I need to use strcpy or strdup...
    as the data is already there in the return value.
    I just can't access it properly in the calling program.

    Comment: when it comes to string handling, C's pretty weak.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by syswizard View Post
    Comment: when it comes to string handling, C's pretty weak.
    No, not really. It can be tricky, yes, but it isn't weak.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by syswizard View Post
    Unfortunately, nothing worked here.
    The closest I came was getting the first string starter back.
    I want a static approach as none of the strings will ever exceed 4 characters.

    char **g_symbols[MAXSYMBOLS][5] // note: strings will be a max of 4 characters wide
    You've got to pick one: you can do either char **g_symbols or char g_symbols[MAXSYMBOLS][5]. You can't do both. (Well, you can, but it's not clear why or how.) It would appear you would want the latter.

    What you had was a two-dimensional array of pointers to pointers to a character.

  10. #10
    Registered User
    Join Date
    Mar 2006
    Posts
    5
    Well guys, after more searching in this forum, I found the answer....
    and it was so, SO simple:
    // placed into the calling program:
    char **g_symbols;
    int i;
    int g_SymbolCnt = 0;
    g_symbols = foo("1234567,1234566", ",", &g_SymbolCnt);
    for (i=0; i<g_SymbolCnt; i++)
    printf("&#37;s", g_symbols[i]);

    1) I modified "foo" to add the count of symbols returned.
    2) no fancy malloc or crazy strdup or strcpy function calls needed
    3) no exotic declarations of array or array of pointers needed

    All of the "work" was done by "foo".
    I tried to thank the author of "foo", but I am unable to "PM" anyone on this forum...
    what's up with that ?
    (Can anyone guess what "foo" really is ?)

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I suggest you use code tags, even for short code. It makes it easier to read.
    PM is a privilege to those with a certain amount of posts, if I'm not mistaken. That's the way it is.
    And you know, you could just pass a pointer to the function that acts as a buffer. The caller (main?) could call the function, passing in a char buffer, a local variable, to fill in the function. No malloc or exotic pointer syntax, and best of all, it's pretty standard to do that way.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Registered User
    Join Date
    Mar 2006
    Posts
    5
    Thanks Elysia...what I discovered from this is that for C language help, all of the code is usually required before the best solution can be provided. Learned my lesson. This would not have taken nearly as long if I had shown more than the stubs and the prototypes, etc.
    For the most part, Indirection and L-values are really driving me crazy.
    I also learned that if the Compiler complains and even warns, I'll got something wrong.
    I've got much more to go on this project.

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by syswizard View Post
    I also learned that if the Compiler complains and even warns, I'll got something wrong.
    Now that's something I like to hear
    You are absolutely right. You should never ignore warnings.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting number
    By Leslie in forum C Programming
    Replies: 8
    Last Post: 05-20-2009, 04:23 AM
  2. ANSI C parsing char array as pointer
    By cyberjunky in forum C Programming
    Replies: 3
    Last Post: 11-30-2008, 03:25 AM
  3. How do i un-SHA1 hash something..
    By willc0de4food in forum C Programming
    Replies: 4
    Last Post: 09-14-2005, 05:59 AM
  4. Could somebody please help me with this C program
    By brett73 in forum C Programming
    Replies: 6
    Last Post: 11-25-2004, 02:19 AM
  5. Half-life SDK, where are the constants?
    By bennyandthejets in forum Game Programming
    Replies: 29
    Last Post: 08-25-2003, 11:58 AM