Allocating memory for struct - when?

Discussion in 'C Programming' started by fix, May 2, 2004.

  1. fix

    fix Guest

    Hi all,
    I am writing a program using some structs, it is not running and I
    believe it is because there's some memory leak - the debugger tells me
    that the code causes the problem is in the malloc function.
    Is there any general rules that tell me when to allocate memory?
    I thought I don't have to if it is a variable that's not a pointer, and
    I have to if it is.
    I am a bit confused about the arrays particularly.
    In normal situations, memory is allocated for array[10] and I don't have
    to do so, but if I want to use a pointer so that the array can be
    dynamic, I shall use *array and allocate the amount of memory I want,
    like array = malloc(sizeof(data_type) * number_of_item), right?
    And if I am storing a "string" (char array) in a struct, what happens.
    I declared it as:

    typedef struct {
    void *obj;
    char key[];
    } HashTableEntry;

    What I do to initialize the object is:

    HashTableEntry *hte = malloc(sizeof(HashTableEntry));
    // "key" is a defined char array
    strcpy(hte->key, key);
    hte->obj = NULL;

    How do the program know how much memory have to be allocated for the
    HashTableEntry? It seems that it is dynamically sized, it depends on the
    char array key.
    And one more thing is, I can't reverse the order of the two members, if
    I do so, the program does not compile. Is there any link between the
    problem I have said above?
    Thanks all!
    fix, May 2, 2004
    #1
    1. Advertising

  2. fix

    Karthik Guest

    fix wrote:
    > Hi all,
    > I am writing a program using some structs, it is not running and I
    > believe it is because there's some memory leak - the debugger tells me
    > that the code causes the problem is in the malloc function.
    > Is there any general rules that tell me when to allocate memory?
    > I thought I don't have to if it is a variable that's not a pointer, and
    > I have to if it is.
    > I am a bit confused about the arrays particularly.
    > In normal situations, memory is allocated for array[10] and I don't have
    > to do so, but if I want to use a pointer so that the array can be
    > dynamic, I shall use *array and allocate the amount of memory I want,
    > like array = malloc(sizeof(data_type) * number_of_item), right?
    > And if I am storing a "string" (char array) in a struct, what happens.
    > I declared it as:
    >
    > typedef struct {
    > void *obj;
    > char key[];

    Whatz this ???

    > } HashTableEntry;
    >
    > What I do to initialize the object is:
    >
    > HashTableEntry *hte = malloc(sizeof(HashTableEntry));
    > // "key" is a defined char array
    > strcpy(hte->key, key);


    This is directly related to the problem 1 mentioned before. You are
    not allocating memory for the field - 'key' . Try this :


    typedef struct {
    void *obj;
    char * key;
    } HashTableEntry;

    HashTableEntry *hte = malloc(sizeof(HashTableEntry));
    // "key" is a defined char array
    key = malloc(sizeof(char) * MAX_CHAR_LEN);
    strcpy(hte->key, key);
    hte->obj = NULL;


    This should help ..
    Dont forget to delete the pointers when deleting the object.


    free(hte) ; // Memory leak


    free(obj);
    free(key);
    free(hte);
    // Pretty cool . But you still need to make sure that indeed the
    fields were allocated to be freed...

    HTH
    --
    Karthik
    Humans please 'removeme_' for my real email.
    Karthik, May 2, 2004
    #2
    1. Advertising

  3. fix

    Karthik Guest

    Karthik wrote:

    > fix wrote:
    >
    >> Hi all,
    >> I am writing a program using some structs, it is not running and I
    >> believe it is because there's some memory leak - the debugger tells me
    >> that the code causes the problem is in the malloc function.
    >> Is there any general rules that tell me when to allocate memory?
    >> I thought I don't have to if it is a variable that's not a pointer,
    >> and I have to if it is.
    >> I am a bit confused about the arrays particularly.
    >> In normal situations, memory is allocated for array[10] and I don't
    >> have to do so, but if I want to use a pointer so that the array can be
    >> dynamic, I shall use *array and allocate the amount of memory I want,
    >> like array = malloc(sizeof(data_type) * number_of_item), right?
    >> And if I am storing a "string" (char array) in a struct, what happens.
    >> I declared it as:
    >>
    >> typedef struct {
    >> void *obj;
    >> char key[];

    >
    > Whatz this ???
    >
    >> } HashTableEntry;
    >>
    >> What I do to initialize the object is:
    >>
    >> HashTableEntry *hte = malloc(sizeof(HashTableEntry));
    >> // "key" is a defined char array
    >> strcpy(hte->key, key);

    >
    >
    > This is directly related to the problem 1 mentioned before. You are
    > not allocating memory for the field - 'key' . Try this :
    >
    >
    > typedef struct {
    > void *obj;
    > char * key;
    > } HashTableEntry;
    >
    > HashTableEntry *hte = malloc(sizeof(HashTableEntry));
    > // "key" is a defined char array
    > key = malloc(sizeof(char) * MAX_CHAR_LEN);

    Instead - better -
    key = malloc(sizeof(char) * (strlen(key) + 1 ));
    // Remember the '\0' char

    > strcpy(hte->key, key);
    > hte->obj = NULL;
    >
    >
    > This should help ..
    > Dont forget to delete the pointers when deleting the object.
    >
    >
    > free(hte) ; // Memory leak
    >
    >
    > free(obj);
    > free(key);
    > free(hte);
    > // Pretty cool . But you still need to make sure that indeed the
    > fields were allocated to be freed...
    >
    > HTH



    --
    Karthik
    Humans please 'removeme_' for my real email.
    Karthik, May 2, 2004
    #3
  4. "fix" <> a écrit dans le message de
    news:c73jer$2ft$...
    > Hi all,


    Hi,

    [snipped]

    > typedef struct {
    > void *obj;
    > char key[];


    key is for the moment an array whose the number of elements is unknown, it's
    an incomplete type (say, flexible array). A thing you can do here is to
    precise the number of elements you want, char key[50]; for example ( a
    #define directive may also help), or use a pointer.

    > } HashTableEntry;
    >
    > What I do to initialize the object is:
    > HashTableEntry *hte = malloc(sizeof(HashTableEntry));


    /* hte tot test */
    if (hte != NULL)
    {

    > // "key" is a defined char array
    > strcpy(hte->key, key);


    Assuming hte->key has now a complete type with a well-known size like said
    above, using strncpy() instead of strcpy() will prevent of writing outside
    the bounds of the hte->key array:

    /* 50-1 to write at least one null terminating character in hte->key, only
    49 characters
    from key are copied into hte->key */
    strncpy(hte->key, key, 50-1);

    > hte->obj = NULL;
    >
    > How do the program know how much memory have to be allocated for the
    > HashTableEntry? It seems that it is dynamically sized, it depends on the
    > char array key.


    Your structure HashTableEntry contains a pointer to a void element and,
    still assuming the member key in the structure is now sized to 50, 50 char
    contiguous elements. The compiler knows the space it needs to store such
    things (IOW, he knows how many bytes are necessary to store an adress of a
    void element and 50 characters. Furthermore, the compiler adds padding bits
    between the members of your structure (not before the first member, here
    obj) to correctly align the data in memory.

    > And one more thing is, I can't reverse the order of the two members, if
    > I do so, the program does not compile. Is there any link between the
    > problem I have said above?


    Yes, since the key member was an incomplete type (remember, flexible array)
    and placed first in the structure, the compiler was unable to determine the
    size of key and where he would have stored obj. If key is placed in the last
    position, it makes sense : I don't know the real policy used by the
    compiler, but it can view key as a pointer to a char.


    Regis
    Régis Troadec, May 2, 2004
    #4
  5. "fix" <> a écrit dans le message de
    news:c73jer$2ft$...
    > Hi all,


    Hi again,

    I forgot to answer to other points.

    > I am writing a program using some structs, it is not running and I
    > believe it is because there's some memory leak - the debugger tells me
    > that the code causes the problem is in the malloc function.
    > Is there any general rules that tell me when to allocate memory?


    The general policy is to allocate memory for your pointers as soon as you
    need to use them and desallocate them as soon as you don't need them anymore
    in your program. IMHO, by using pointers, allocating all the needed memory
    at the beginning of a program to desallocate it at the end is nonsense.

    > I thought I don't have to if it is a variable that's not a pointer, and
    > I have to if it is.
    > I am a bit confused about the arrays particularly.
    > In normal situations, memory is allocated for array[10] and I don't have
    > to do so, but if I want to use a pointer so that the array can be
    > dynamic, I shall use *array and allocate the amount of memory I want,


    ....or array : array->something against (*array).something, which one is
    easier to read?

    > like array = malloc(sizeof(data_type) * number_of_item), right?


    Right.

    Regis
    Régis Troadec, May 2, 2004
    #5
  6. fix

    fix Guest

    Karthik wrote:

    > Karthik wrote:
    >
    >> fix wrote:
    >>
    >>> Hi all,
    >>> I am writing a program using some structs, it is not running and I
    >>> believe it is because there's some memory leak - the debugger tells
    >>> me that the code causes the problem is in the malloc function.
    >>> Is there any general rules that tell me when to allocate memory?
    >>> I thought I don't have to if it is a variable that's not a pointer,
    >>> and I have to if it is.
    >>> I am a bit confused about the arrays particularly.
    >>> In normal situations, memory is allocated for array[10] and I don't
    >>> have to do so, but if I want to use a pointer so that the array can
    >>> be dynamic, I shall use *array and allocate the amount of memory I
    >>> want, like array = malloc(sizeof(data_type) * number_of_item), right?
    >>> And if I am storing a "string" (char array) in a struct, what happens.
    >>> I declared it as:
    >>>
    >>> typedef struct {
    >>> void *obj;
    >>> char key[];

    >>
    >>
    >> Whatz this ???


    Just like the function header some_fct(int some_int, char char_array[]),
    I can't do that?

    >>> } HashTableEntry;
    >>>
    >>> What I do to initialize the object is:
    >>>
    >>> HashTableEntry *hte = malloc(sizeof(HashTableEntry));
    >>> // "key" is a defined char array
    >>> strcpy(hte->key, key);

    >>
    >>
    >>
    >> This is directly related to the problem 1 mentioned before. You
    >> are not allocating memory for the field - 'key' . Try this :
    >>
    >>
    >> typedef struct {
    >> void *obj;
    >> char * key;
    >> } HashTableEntry;
    >>
    >> HashTableEntry *hte = malloc(sizeof(HashTableEntry));
    >> // "key" is a defined char array
    >> key = malloc(sizeof(char) * MAX_CHAR_LEN);

    >
    > Instead - better -
    > key = malloc(sizeof(char) * (strlen(key) + 1 ));
    > // Remember the '\0' char


    Actually I want to store the string in the struct, not pointing to
    somewhere out there, is that possible?

    >> strcpy(hte->key, key);
    >> hte->obj = NULL;
    >>
    >>
    >> This should help ..
    >> Dont forget to delete the pointers when deleting the object.
    >>
    >>
    >> free(hte) ; // Memory leak
    >>
    >>
    >> free(obj);
    >> free(key);
    >> free(hte);
    >> // Pretty cool . But you still need to make sure that indeed the
    >> fields were allocated to be freed...
    >>
    >> HTH

    >
    >
    >
    fix, May 2, 2004
    #6
  7. fix

    fix Guest

    Régis Troadec wrote:

    > "fix" <> a écrit dans le message de
    > news:c73jer$2ft$...
    >
    >>Hi all,

    >
    >
    > Hi again,
    >
    > I forgot to answer to other points.
    >
    >
    >>I am writing a program using some structs, it is not running and I
    >>believe it is because there's some memory leak - the debugger tells me
    >>that the code causes the problem is in the malloc function.
    >>Is there any general rules that tell me when to allocate memory?

    >
    >
    > The general policy is to allocate memory for your pointers as soon as you
    > need to use them and desallocate them as soon as you don't need them anymore
    > in your program. IMHO, by using pointers, allocating all the needed memory
    > at the beginning of a program to desallocate it at the end is nonsense.
    >
    >
    >>I thought I don't have to if it is a variable that's not a pointer, and
    >>I have to if it is.
    >>I am a bit confused about the arrays particularly.
    >>In normal situations, memory is allocated for array[10] and I don't have
    >>to do so, but if I want to use a pointer so that the array can be
    >>dynamic, I shall use *array and allocate the amount of memory I want,

    >
    >
    > ...or array : array->something against (*array).something, which one is
    > easier to read?


    How could I use it like an array?
    I can do array[0], .... array[5] if I declared int array[10],
    and *array to access the data and array++ to go to the next one.

    >>like array = malloc(sizeof(data_type) * number_of_item), right?

    >
    >
    > Right.
    >
    > Regis
    >
    >
    fix, May 2, 2004
    #7
  8. fix

    fix Guest

    Régis Troadec wrote:

    > "fix" <> a écrit dans le message de
    > news:c73jer$2ft$...
    >
    >>Hi all,

    >
    >
    > Hi,
    >
    > [snipped]
    >
    >
    >>typedef struct {
    >>void *obj;
    >>char key[];

    >
    >
    > key is for the moment an array whose the number of elements is unknown, it's
    > an incomplete type (say, flexible array). A thing you can do here is to
    > precise the number of elements you want, char key[50]; for example ( a
    > #define directive may also help), or use a pointer.


    But I don't know how long the char array will be and I want to store it
    in the struct.

    >>} HashTableEntry;
    >>
    >>What I do to initialize the object is:
    >>HashTableEntry *hte = malloc(sizeof(HashTableEntry));

    >
    >
    > /* hte tot test */
    > if (hte != NULL)
    > {
    >
    >
    >>// "key" is a defined char array
    >>strcpy(hte->key, key);

    >
    >
    > Assuming hte->key has now a complete type with a well-known size like said
    > above, using strncpy() instead of strcpy() will prevent of writing outside
    > the bounds of the hte->key array:
    >
    > /* 50-1 to write at least one null terminating character in hte->key, only
    > 49 characters
    > from key are copied into hte->key */
    > strncpy(hte->key, key, 50-1);
    >
    >
    >>hte->obj = NULL;
    >>
    >>How do the program know how much memory have to be allocated for the
    >>HashTableEntry? It seems that it is dynamically sized, it depends on the
    >>char array key.

    >
    >
    > Your structure HashTableEntry contains a pointer to a void element and,
    > still assuming the member key in the structure is now sized to 50, 50 char
    > contiguous elements. The compiler knows the space it needs to store such
    > things (IOW, he knows how many bytes are necessary to store an adress of a
    > void element and 50 characters. Furthermore, the compiler adds padding bits
    > between the members of your structure (not before the first member, here
    > obj) to correctly align the data in memory.
    >
    >
    >>And one more thing is, I can't reverse the order of the two members, if
    >>I do so, the program does not compile. Is there any link between the
    >>problem I have said above?

    >
    >
    > Yes, since the key member was an incomplete type (remember, flexible array)
    > and placed first in the structure, the compiler was unable to determine the
    > size of key and where he would have stored obj. If key is placed in the last
    > position, it makes sense : I don't know the real policy used by the
    > compiler, but it can view key as a pointer to a char.
    >
    >
    > Regis
    >
    >
    fix, May 2, 2004
    #8
  9. "fix" <> a ecrit dans le message de
    news:c73s1d$90e$...
    > >
    > > key is for the moment an array whose the number of elements is unknown,

    it's
    > > an incomplete type (say, flexible array). A thing you can do here is to
    > > precise the number of elements you want, char key[50]; for example ( a
    > > #define directive may also help), or use a pointer.

    >
    > But I don't know how long the char array will be and I want to store it
    > in the struct.
    >


    Don't you know at least the maximum size?

    Regis
    Regis Troadec, May 2, 2004
    #9
  10. "fix" <> a ecrit dans le message de
    news:c73rv2$90e$...
    > >
    > >>I thought I don't have to if it is a variable that's not a pointer, and
    > >>I have to if it is.
    > >>I am a bit confused about the arrays particularly.
    > >>In normal situations, memory is allocated for array[10] and I don't have
    > >>to do so, but if I want to use a pointer so that the array can be
    > >>dynamic, I shall use *array and allocate the amount of memory I want,

    > >
    > >
    > > ...or array : array->something against (*array).something, which one is
    > > easier to read?

    >
    > How could I use it like an array?
    > I can do array[0], .... array[5] if I declared int array[10],
    > and *array to access the data and array++ to go to the next one.


    It was a general comment about pointers. If array is a pointer in your case,
    you can still use the subscript notation array[i-th] to access the elements
    when it's allocated.

    Regis
    Regis Troadec, May 2, 2004
    #10
  11. fix

    Chris Torek Guest

    After carefully matching up the > marks, I believe that:

    >>> fix wrote:
    >>>> typedef struct {
    >>>> void *obj;
    >>>> char key[];
    >>>> } HashTableEntry;


    and:

    >> Karthik wrote:
    >>> Whatz this ???


    In article <c73rmn$90e$> fix <> wrote:
    >Just like the function header some_fct(int some_int, char char_array[]),
    >I can't do that?


    Not in C89. In C99, it is allowed, and is a new construct called
    a "flexible array member" of a structure.

    Note that the structure type (which is unnamed) is a complete type,
    but is always smaller than the "final" size you really want to use.
    Such structures essentially always must be allocated via malloc(),
    and dealt with through pointers. Suppose that the "key" is a
    C-style string that contains four characters such as "abcd", and
    thus is five bytes long: {'a', 'b', 'c', 'd', '\0'}. Given a
    pointer to the alias for the unnamed structure type:

    HashTableEntry /* an alias for struct <name_not_available> */ *p;

    you would then write:

    p = malloc((1 * sizeof *p) + 5);

    or equivalently:

    p = malloc(sizeof *p + 5);

    The first form follows the time-tested, "comp.lang.c approved" :)
    idiom of:

    var = malloc(N * sizeof *var);

    where N is the number of objects to allocate. Flexible-array-member
    structures almost invariably have to be allocated one at a time
    anyway (so that N must always be 1) and need some additional number
    added to account for the array added to the end. To continue to
    follow the "comp.lang.c idiom", as it were, it really should read:

    var = malloc(sizeof *var + N * sizeof *var->flexible_array_member);

    or in this case:

    p = malloc(sizeof *p + 5 * sizeof *p->key);

    since the goal is to allocate, in one swoop, both one (1) "struct"
    object *and* just enough extra space for N (5, here) array-elements
    in the F.A.M. appended to the structure. But we know for certain
    (because the language definition says so) that sizeof(char) is
    just 1, and 5 * 1 is of course 5.

    In C89 (also called C90 sometimes), flexible array members do not
    exist. As you can see in the FAQ, there is a "cheat" that usually
    works, in which one declares the structure as having an array of
    size 1:

    typedef struct HashTableEntry HashTableEntry;

    struct HashTableEntry {
    void *obj;
    char key[1];
    };

    but this is technically illegal, despite the extremely good chance
    of getting away with it (see FAQ #2.6). In this case, the array
    p->key has one element already -- which is just enough room for
    the '\0' that terminates any C-style string -- so the call would
    look like:

    p = malloc(sizeof *p + 4); /* '\0' already accounted-for */

    This again uses the fact that sizeof(char) is just 1 -- if the
    faked F.A.M. had some element-type other than "char", e.g.:

    struct zog {
    int zog_len; /* number of zogs */
    int zog_val[]; /* and the zogs, as F.A.M. */
    };

    then we would need code more like:

    struct zog *p;
    ...
    p = malloc(sizeof *p + n * sizeof p->zog_val[0]);
    if (p == NULL) ... handle memory-allocation failure ...
    p->zog_len = n;
    ... set up p->zog_val for i in [0..n) ...

    In this malloc() call, I prefer suffixing p->zog_val with [0],
    rather than writing the "*" in front, but this is just a style
    issue.

    Finally, I should note that the:

    > function header some_fct(int some_int, char char_array[])


    does *not* declare "char_array" as an array. See section 6 of the
    FAQ (in particular question 6.4).
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
    Chris Torek, May 3, 2004
    #11
  12. fix

    Al Bowers Guest

    fix wrote:
    >
    > R?is Troadec wrote:
    >
    >
    >>"fix" <> a ?rit dans le message de
    >>news:c73jer$2ft$...
    >>
    >>
    >>>Hi all,

    >>
    >>
    >>Hi,
    >>
    >>[snipped]
    >>
    >>
    >>
    >>>typedef struct {
    >>>void *obj;
    >>>char key[];

    >>
    >>
    >>key is for the moment an array whose the number of elements is unknown, it's
    >>an incomplete type (say, flexible array). A thing you can do here is to
    >>precise the number of elements you want, char key[50]; for example ( a
    >>#define directive may also help), or use a pointer.

    >
    >
    > But I don't know how long the char array will be and I want to store it
    > in the struct.
    >


    Then I suggest you make the member key type char *.
    You then allocated key to strlen of the key string + 1.
    I would put the allocations in a function with one parameter
    being the key string and the other parameter being a pointer
    to the void *obj. The function would return a pointer to the
    newly allocated and assigned HastTableEntry.

    Example:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>

    typedef struct {
    void *obj;
    char *key;
    }HashTableEntry;

    typedef struct EXAMPLEDATA
    {
    char ip[16];
    char name[64];
    }EXAMPLEDATA;

    HashTableEntry *addHashTableEntry(const char *key, void *data);
    void freeHashTableEntry(HashTableEntry **node);

    int main(void)
    {
    EXAMPLEDATA data = {"192.168.42.007","www.abcd.com"};
    HashTableEntry *node = NULL;

    /* For example say key is AbcDeFG123 */
    node = addHashTableEntry("AbcDeFG123", &data);
    if(node)
    printf("node->key = \"%s\"\n"
    "node->obj points to struct containing an\n"
    "ip of \"%s\" and a\ndomain name of \"%s\"\n",
    node->key,((EXAMPLEDATA *)node->obj)->ip,
    ((EXAMPLEDATA *)node->obj)->name);
    freeHashTableEntry(&node);
    puts("\nThe allocations have been freed\nExiting....\n");
    return 0;
    }

    HashTableEntry *addHashTableEntry(const char *key, void *data)
    {
    HashTableEntry *new;

    if((new = malloc(sizeof *new)) == NULL) return NULL;
    if((new->key = malloc(strlen(key)+1)) == NULL)
    {
    free(new);
    return NULL;
    }
    strcpy(new->key,key);
    new->obj = data;
    return new;
    }

    void freeHashTableEntry(HashTableEntry **node)
    {
    if(*node) free((*node)->key);
    free(*node);
    *node = NULL;
    return;
    }



    --
    Al Bowers
    Tampa, Fl USA
    mailto: (remove the x to send email)
    http://www.geocities.com/abowers822/
    Al Bowers, May 3, 2004
    #12
  13. fix

    Old Wolf Guest

    fix <> wrote:
    > I am writing a program using some structs, it is not running and I
    > believe it is because there's some memory leak - the debugger tells me
    > that the code causes the problem is in the malloc function.


    > typedef struct {
    > void *obj;
    > char key[];
    > } HashTableEntry;


    BTW, you can't have arrays of these.

    > What I do to initialize the object is:
    >
    > HashTableEntry *hte = malloc(sizeof(HashTableEntry));
    > // "key" is a defined char array
    > strcpy(hte->key, key);
    > hte->obj = NULL;


    What you should be doing is:
    HashTableEntry *hte = malloc(strlen(key) + 1 + sizeof *hte);
    strcpy(hte->key, key);
    hte->obj = NULL;

    Note that sizeof(*hte) is the same as sizeof(void*), the member "key"
    does not have a size that the compiler knows about. You won't be
    able to access the size of the entry later on in your code.
    Because of this, you can't safely put a new value into the key (unless
    it has the same length). So I would consider making key "const char"
    instead of "char" (and casting it in the call to strcpy).

    > And one more thing is, I can't reverse the order of the two members


    Obviously not, how would the compiler know how much memory to
    leave before the start of "obj" ?

    If this is all confusing to you, you might want to consider
    the other poster's suggestion of having "char *key;" and allocating
    key with malloc too; although it seems to me that this is a perfect
    example of a situation that flexible array members were designed for.
    Old Wolf, May 3, 2004
    #13
  14. fix

    fix Guest

    Chris Torek wrote:
    ... snip ..
    >
    > HashTableEntry /* an alias for struct <name_not_available> */ *p;
    >
    > you would then write:
    >
    > p = malloc((1 * sizeof *p) + 5);
    >
    > or equivalently:
    >
    > p = malloc(sizeof *p + 5);
    >


    So in short, I have to allocate memory for the sizeof(the_struct) +
    sizeof(flexible_array_member). Maybe that's why my program just crashes
    if I allocate memory just for the struct. But I wonder why
    sizeof(the_struct) will only return the size without the flexible array
    member, is it designed to be? It looked a bit odd to me.

    ... snip ..
    >
    > Finally, I should note that the:
    >
    >
    >>function header some_fct(int some_int, char char_array[])

    >
    >
    > does *not* declare "char_array" as an array. See section 6 of the
    > FAQ (in particular question 6.4).


    OK, I got it, thanks.
    fix, May 3, 2004
    #14
  15. fix

    fix Guest

    Regis Troadec wrote:

    > "fix" <> a ecrit dans le message de
    > news:c73s1d$90e$...
    >
    >>>key is for the moment an array whose the number of elements is unknown,

    >
    > it's
    >
    >>>an incomplete type (say, flexible array). A thing you can do here is to
    >>>precise the number of elements you want, char key[50]; for example ( a
    >>>#define directive may also help), or use a pointer.

    >>
    >>But I don't know how long the char array will be and I want to store it
    >>in the struct.
    >>

    >
    >
    > Don't you know at least the maximum size?
    >
    > Regis
    >

    It is the users to decide, I really wouldn't know in advance.
    fix, May 3, 2004
    #15
  16. -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    fix wrote:
    |
    | Chris Torek wrote:
    | .. snip ..
    |
    |> HashTableEntry /* an alias for struct <name_not_available> */ *p;
    |>
    |>you would then write:
    |>
    |> p = malloc((1 * sizeof *p) + 5);
    |>
    |>or equivalently:
    |>
    |> p = malloc(sizeof *p + 5);
    |>
    |
    |
    | So in short, I have to allocate memory for the sizeof(the_struct) +
    | sizeof(flexible_array_member). Maybe that's why my program just crashes
    | if I allocate memory just for the struct. But I wonder why
    | sizeof(the_struct) will only return the size without the flexible array
    | member, is it designed to be? It looked a bit odd to me.
    |

    Well, because sizeof(flexible_array_member) is unknown, that what makes
    it flexible. So instead, sizeof(the_struct) just gives you the size of
    the stuff that *is* known. Of course, sizeof(*flexible_array_member)
    (one element of the array) is known, so the size of the whole lot is
    sizeof(the_struct)+n*sizeof(*flexible_array_member), where n is a value
    unknown to the compiler.

    Ross
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.2.3 (GNU/Linux)
    Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

    iD8DBQFAlvl99bR4xmappRARAvhwAJ0eZYrRtbOiHwVA6mvlj4xKsNabPACdHtxv
    hsHwRMJW4hTrc8xCnTA9lz0=
    =TZvV
    -----END PGP SIGNATURE-----
    Ross Kendall Axe, May 4, 2004
    #16
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Serve Laurijssen

    allocating inner struct array

    Serve Laurijssen, Jul 24, 2003, in forum: C Programming
    Replies:
    3
    Views:
    351
    Dan Pop
    Jul 25, 2003
  2. Chris Fogelklou
    Replies:
    36
    Views:
    1,356
    Chris Fogelklou
    Apr 20, 2004
  3. Replies:
    7
    Views:
    403
    Old Wolf
    Feb 23, 2005
  4. Rakesh Kumar
    Replies:
    5
    Views:
    675
    James Kanze
    Dec 21, 2007
  5. Replies:
    0
    Views:
    455
Loading...

Share This Page