Allocating memory for struct - when?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • fix

    Allocating memory for struct - when?

    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(d ata_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(H ashTableEntry)) ;
    // "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!

  • Karthik

    #2
    Re: Allocating memory for struct - when?

    fix wrote:[color=blue]
    > 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(d ata_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[];[/color]
    Whatz this ???
    [color=blue]
    > } HashTableEntry;
    >
    > What I do to initialize the object is:
    >
    > HashTableEntry *hte = malloc(sizeof(H ashTableEntry)) ;
    > // "key" is a defined char array
    > strcpy(hte->key, key);[/color]

    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(H ashTableEntry)) ;
    // "key" is a defined char array
    key = malloc(sizeof(c har) * 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.

    Comment

    • Karthik

      #3
      Re: Allocating memory for struct - when?

      Karthik wrote:
      [color=blue]
      > fix wrote:
      >[color=green]
      >> 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(d ata_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[];[/color]
      >
      > Whatz this ???
      >[color=green]
      >> } HashTableEntry;
      >>
      >> What I do to initialize the object is:
      >>
      >> HashTableEntry *hte = malloc(sizeof(H ashTableEntry)) ;
      >> // "key" is a defined char array
      >> strcpy(hte->key, key);[/color]
      >
      >
      > 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(H ashTableEntry)) ;
      > // "key" is a defined char array
      > key = malloc(sizeof(c har) * MAX_CHAR_LEN);[/color]
      Instead - better -
      key = malloc(sizeof(c har) * (strlen(key) + 1 ));
      // Remember the '\0' char
      [color=blue]
      > 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[/color]


      --
      Karthik
      Humans please 'removeme_' for my real email.

      Comment

      • Régis Troadec

        #4
        Re: Allocating memory for struct - when?


        "fix" <fix@here.com > a écrit dans le message de
        news:c73jer$2ft $1@news.tamu.ed u...[color=blue]
        > Hi all,[/color]

        Hi,

        [snipped]
        [color=blue]
        > typedef struct {
        > void *obj;
        > char key[];[/color]

        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.
        [color=blue]
        > } HashTableEntry;
        >
        > What I do to initialize the object is:
        > HashTableEntry *hte = malloc(sizeof(H ashTableEntry)) ;[/color]

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

        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);
        [color=blue]
        > 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.[/color]

        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.
        [color=blue]
        > 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?[/color]

        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


        Comment

        • Régis Troadec

          #5
          Re: Allocating memory for struct - when?


          "fix" <fix@here.com > a écrit dans le message de
          news:c73jer$2ft $1@news.tamu.ed u...[color=blue]
          > Hi all,[/color]

          Hi again,

          I forgot to answer to other points.
          [color=blue]
          > 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?[/color]

          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.
          [color=blue]
          > 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,[/color]

          ....or array : array->something against (*array).someth ing, which one is
          easier to read?
          [color=blue]
          > like array = malloc(sizeof(d ata_type) * number_of_item) , right?[/color]

          Right.

          Regis


          Comment

          • fix

            #6
            Re: Allocating memory for struct - when?



            Régis Troadec wrote:
            [color=blue]
            > "fix" <fix@here.com > a écrit dans le message de
            > news:c73jer$2ft $1@news.tamu.ed u...
            >[color=green]
            >>Hi all,[/color]
            >
            >
            > Hi again,
            >
            > I forgot to answer to other points.
            >
            >[color=green]
            >>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?[/color]
            >
            >
            > 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.
            >
            >[color=green]
            >>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,[/color]
            >
            >
            > ...or array : array->something against (*array).someth ing, which one is
            > easier to read?[/color]

            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.
            [color=blue][color=green]
            >>like array = malloc(sizeof(d ata_type) * number_of_item) , right?[/color]
            >
            >
            > Right.
            >
            > Regis
            >
            >[/color]

            Comment

            • fix

              #7
              Re: Allocating memory for struct - when?



              Karthik wrote:
              [color=blue]
              > Karthik wrote:
              >[color=green]
              >> fix wrote:
              >>[color=darkred]
              >>> 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(d ata_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[];[/color]
              >>
              >>
              >> Whatz this ???[/color][/color]

              Just like the function header some_fct(int some_int, char char_array[]),
              I can't do that?
              [color=blue][color=green][color=darkred]
              >>> } HashTableEntry;
              >>>
              >>> What I do to initialize the object is:
              >>>
              >>> HashTableEntry *hte = malloc(sizeof(H ashTableEntry)) ;
              >>> // "key" is a defined char array
              >>> strcpy(hte->key, key);[/color]
              >>
              >>
              >>
              >> 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(H ashTableEntry)) ;
              >> // "key" is a defined char array
              >> key = malloc(sizeof(c har) * MAX_CHAR_LEN);[/color]
              >
              > Instead - better -
              > key = malloc(sizeof(c har) * (strlen(key) + 1 ));
              > // Remember the '\0' char[/color]

              Actually I want to store the string in the struct, not pointing to
              somewhere out there, is that possible?
              [color=blue][color=green]
              >> 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[/color]
              >
              >
              >[/color]

              Comment

              • fix

                #8
                Re: Allocating memory for struct - when?



                Régis Troadec wrote:
                [color=blue]
                > "fix" <fix@here.com > a écrit dans le message de
                > news:c73jer$2ft $1@news.tamu.ed u...
                >[color=green]
                >>Hi all,[/color]
                >
                >
                > Hi,
                >
                > [snipped]
                >
                >[color=green]
                >>typedef struct {
                >>void *obj;
                >>char key[];[/color]
                >
                >
                > 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.[/color]

                But I don't know how long the char array will be and I want to store it
                in the struct.
                [color=blue][color=green]
                >>} HashTableEntry;
                >>
                >>What I do to initialize the object is:
                >>HashTableEntr y *hte = malloc(sizeof(H ashTableEntry)) ;[/color]
                >
                >
                > /* hte tot test */
                > if (hte != NULL)
                > {
                >
                >[color=green]
                >>// "key" is a defined char array
                >>strcpy(hte->key, key);[/color]
                >
                >
                > 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);
                >
                >[color=green]
                >>hte->obj = NULL;
                >>
                >>How do the program know how much memory have to be allocated for the
                >>HashTableEntr y? It seems that it is dynamically sized, it depends on the
                >>char array key.[/color]
                >
                >
                > 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.
                >
                >[color=green]
                >>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?[/color]
                >
                >
                > 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
                >
                >[/color]

                Comment

                • Regis Troadec

                  #9
                  Re: Allocating memory for struct - when?


                  "fix" <fix@here.com > a ecrit dans le message de
                  news:c73s1d$90e $3@news.tamu.ed u...[color=blue][color=green]
                  > >
                  > > key is for the moment an array whose the number of elements is unknown,[/color][/color]
                  it's[color=blue][color=green]
                  > > 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.[/color]
                  >
                  > But I don't know how long the char array will be and I want to store it
                  > in the struct.
                  >[/color]

                  Don't you know at least the maximum size?

                  Regis


                  Comment

                  • Regis Troadec

                    #10
                    Re: Allocating memory for struct - when?


                    "fix" <fix@here.com > a ecrit dans le message de
                    news:c73rv2$90e $2@news.tamu.ed u...[color=blue][color=green]
                    > >[color=darkred]
                    > >>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,[/color]
                    > >
                    > >
                    > > ...or array : array->something against (*array).someth ing, which one is
                    > > easier to read?[/color]
                    >
                    > 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.[/color]

                    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


                    Comment

                    • Al Bowers

                      #11
                      Re: Allocating memory for struct - when?



                      fix wrote:[color=blue]
                      >
                      > R?is Troadec wrote:
                      >
                      >[color=green]
                      >>"fix" <fix@here.com > a ?rit dans le message de
                      >>news:c73jer$2 ft$1@news.tamu. edu...
                      >>
                      >>[color=darkred]
                      >>>Hi all,[/color]
                      >>
                      >>
                      >>Hi,
                      >>
                      >>[snipped]
                      >>
                      >>
                      >>[color=darkred]
                      >>>typedef struct {
                      >>>void *obj;
                      >>>char key[];[/color]
                      >>
                      >>
                      >>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.[/color]
                      >
                      >
                      > But I don't know how long the char array will be and I want to store it
                      > in the struct.
                      >[/color]

                      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 *addHashTableEn try(const char *key, void *data);
                      void freeHashTableEn try(HashTableEn try **node);

                      int main(void)
                      {
                      EXAMPLEDATA data = {"192.168.42.00 7","www.abcd.co m"};
                      HashTableEntry *node = NULL;

                      /* For example say key is AbcDeFG123 */
                      node = addHashTableEnt ry("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,((EXAMPLED ATA *)node->obj)->ip,
                      ((EXAMPLEDATA *)node->obj)->name);
                      freeHashTableEn try(&node);
                      puts("\nThe allocations have been freed\nExiting. ...\n");
                      return 0;
                      }

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

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

                      void freeHashTableEn try(HashTableEn try **node)
                      {
                      if(*node) free((*node)->key);
                      free(*node);
                      *node = NULL;
                      return;
                      }



                      --
                      Al Bowers
                      Tampa, Fl USA
                      mailto: xabowers@myrapi dsys.com (remove the x to send email)
                      Latest news coverage, email, free stock quotes, live scores and video are just the beginning. Discover more every day at Yahoo!


                      Comment

                      • Chris Torek

                        #12
                        Re: Allocating memory for struct - when?

                        After carefully matching up the > marks, I believe that:
                        [color=blue][color=green][color=darkred]
                        >>> fix wrote:
                        >>>> typedef struct {
                        >>>> void *obj;
                        >>>> char key[];
                        >>>> } HashTableEntry;[/color][/color][/color]

                        and:
                        [color=blue][color=green]
                        >> Karthik wrote:[color=darkred]
                        >>> Whatz this ???[/color][/color][/color]

                        In article <c73rmn$90e$1@n ews.tamu.edu> fix <fix@here.com > wrote:[color=blue]
                        >Just like the function header some_fct(int some_int, char char_array[]),
                        >I can't do that?[/color]

                        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_avail able> */ *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[i] 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:
                        [color=blue]
                        > function header some_fct(int some_int, char char_array[])[/color]

                        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.

                        Comment

                        • Old Wolf

                          #13
                          Re: Allocating memory for struct - when?

                          fix <fix@here.com > wrote:[color=blue]
                          > 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.[/color]
                          [color=blue]
                          > typedef struct {
                          > void *obj;
                          > char key[];
                          > } HashTableEntry;[/color]

                          BTW, you can't have arrays of these.
                          [color=blue]
                          > What I do to initialize the object is:
                          >
                          > HashTableEntry *hte = malloc(sizeof(H ashTableEntry)) ;
                          > // "key" is a defined char array
                          > strcpy(hte->key, key);
                          > hte->obj = NULL;[/color]

                          What you should be doing is:
                          HashTableEntry *hte = malloc(strlen(k ey) + 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).
                          [color=blue]
                          > And one more thing is, I can't reverse the order of the two members[/color]

                          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.

                          Comment

                          • fix

                            #14
                            Re: Allocating memory for struct - when?



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

                            So in short, I have to allocate memory for the sizeof(the_stru ct) +
                            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_stru ct) will only return the size without the flexible array
                            member, is it designed to be? It looked a bit odd to me.

                            ... snip ..[color=blue]
                            >
                            > Finally, I should note that the:
                            >
                            >[color=green]
                            >>function header some_fct(int some_int, char char_array[])[/color]
                            >
                            >
                            > does *not* declare "char_array " as an array. See section 6 of the
                            > FAQ (in particular question 6.4).[/color]

                            OK, I got it, thanks.

                            Comment

                            • fix

                              #15
                              Re: Allocating memory for struct - when?

                              Regis Troadec wrote:
                              [color=blue]
                              > "fix" <fix@here.com > a ecrit dans le message de
                              > news:c73s1d$90e $3@news.tamu.ed u...
                              >[color=green][color=darkred]
                              >>>key is for the moment an array whose the number of elements is unknown,[/color][/color]
                              >
                              > it's
                              >[color=green][color=darkred]
                              >>>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.[/color]
                              >>
                              >>But I don't know how long the char array will be and I want to store it
                              >>in the struct.
                              >>[/color]
                              >
                              >
                              > Don't you know at least the maximum size?
                              >
                              > Regis
                              >[/color]
                              It is the users to decide, I really wouldn't know in advance.

                              Comment

                              Working...