Problem with an array of pointers

Discussion in 'C Programming' started by Rob Thorpe, Oct 6, 2004.

  1. Rob Thorpe

    Rob Thorpe Guest

    I have a set of data structures that are collected together in array.
    This array is in turn packaged in a struct itself. The structs look
    like this:-

    struct index_entry_t
    {
    char *id;
    char *description;
    };
    typedef struct index_entry_t index_entry_t;

    struct index_t
    {
    int no_of_entries;
    index_entry_t *table[];
    };
    typedef struct index_t index_t;

    The member 'table' of index_t contains an array of pointers to
    index_entry_t's.

    The program then goes on to make a pointer to an index_t. The result
    is shown below:-
    _____________
    i ------>|index_t |
    |_____________|
    |no_of_entries|
    |_____________|
    |table | _______ _____________
    |____________--------->| ----------------->|index_entry_t|
    |_______| |_____________|
    | ----------> |id |
    |_______| |_____________|
    | ----------> |description |
    |_______| |_____________|
    | ... |

    My problem is, I can't find the right syntax to access the members, ie
    the index_entry_t's.

    To me these seem the right ways:

    (i->table[n])->id
    or
    *(i->table[n]).id

    but they both give the error:
    test_ind2.c:86: error: request for member `description' in something
    not a structure or union

    on my compiler (gcc).

    What is wrong?
     
    Rob Thorpe, Oct 6, 2004
    #1
    1. Advertisements

  2. Rob Thorpe

    pete Guest

    This line:
    index_entry_t *table[];
    is not standard C.
     
    pete, Oct 6, 2004
    #2
    1. Advertisements

  3. And why do you say this? Has the current standard been repealed? Have
    flexible array members been removed from the standard?
     
    Martin Ambuhl, Oct 6, 2004
    #3
  4. Rob Thorpe

    Old Wolf Guest

    It's a flexible array member (N869 6.7.2.1#15)
    This was introduced in ISO 9899:1999 as a legal alternative
    to the 'struct hack'.

    To the OP: the code compiles without error for me (using
    gcc 3.4.2 in C99 mode), can you post the exact code that
    gives the problem? My code was:

    int main(void)
    {
    struct index_t *i;
    i->table[4]->id;
    }
     
    Old Wolf, Oct 7, 2004
    #4
  5. Rob Thorpe

    pete Guest

    I frequently forget about C99 and make mistakes like that.
     
    pete, Oct 7, 2004
    #5
  6. Obviously in your real code there is some value specified for the
    array size.
    snip diagram
    This is correct but the parentheses are unnecessary.
    This is not correct since . has higher precedence than *. You need
    (*i->table[n]).id
    This error must be for a different line of code since the description
    member is not referenced in either.
    Post the real code. Preferably a small complete compilable example
    that demonstrates the problem.


    <<Remove the del for email>>
     
    Barry Schwarz, Oct 7, 2004
    #6
  7. Rob Thorpe

    Rob Thorpe Guest

    Aha, this construct is only legal C99. Unfortunately, my code must
    work on a C90 or C++ compiler.

    It seems to make perfect sense to write "index_entry_t *table[];",
    after all I want a pointer to an array of index_entry_t's and I want
    the pointer named table. The new standard makes more sense than the
    old on this point.

    If I replace this with index_entry_t **table; it works.
    Thanks to everyone who posted.
     
    Rob Thorpe, Oct 7, 2004
    #7
  8. Rob Thorpe

    John Bode Guest

    [snip diagram]

    Two questions:

    1. Which version of gcc?
    2. Are you sure you have the right statement for the error?

    The first form should work just fine (type of i->table[n] should be
    index_entry_t *), unless I've missed something. The second is wrong,
    it should be (*i->table[n]).id (remember, x->y is equivalent to
    (*x).y, not *(x).y).
     
    John Bode, Oct 7, 2004
    #8
  9. Rob Thorpe

    Old Wolf Guest

    In a declaration, square brackets indicate an array.
    The star indicates a pointer.
    When both are combined in this case, the square brackets
    have precedence; the original 'table' is an array of
    pointers, not a pointer-to-array.
    Naturally. This declares a pointer (which you can then
    point to the first member of an array).

    Read through chapter 6 of the FAQ if you haven't already (you
    may find a few useful tidbits you didn't already know).
    I'm not sure that it does what you think it does; it declares
    an array of pointers, where the size of the array is unknown.
    The only correct way to allocate a struct like this is:

    struct index_t *ptr = malloc(sizeof (struct index_t)
    + sizeof(index_entry_t *) * N);

    and then you can access ptr->table[0], ptr->table[1],
    and so on, up to ptr->table[N-1] safely.

    In C90 it wasn't possible to have a structure that
    contained an array whose size wasn't known until runtime.
    The common workaround was called the 'struct hack':
    basically the same as what we just did, execpt that the
    array member was declared as
    index_entry_t *table[1];
    and you would go ahead an access table[2] etc. anyway.
     
    Old Wolf, Oct 7, 2004
    #9
  10. Rob Thorpe

    Rob Thorpe Guest

    That's what I meant, when I coded it, I forgot and confused myself in
    the time since. The reasons of the error seems obvious now.
    That's just what I've been doing in the past couple of days,
    interesting reading.
    I see. That's not what I want since I can't tell how many
    index_entry_t's there will be when I initialise the index_t. I need
    to malloc 'table' separately.
    I read about this, but never understood why anyone would want to do
    it, I get it now, though it looks best avoided.
     
    Rob Thorpe, Oct 8, 2004
    #10
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.