error when allocating memory using a pointer inside a struct via a function

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • elmafiacs@yahoo.es

    error when allocating memory using a pointer inside a struct via a function

    I need some help with an error I'm getting...
    Sorry if this is basic stuff, but I'm still a newbie on C programming
    (working up, though).
    Also, I'm using gcc as my compiler ('gcc t.c -o t', no strange stuff).
    Sorry about the long subject, I didn't know how to explain it better...

    struct small {
    int num;
    };

    struct big {
    struct small *small_thing;
    };

    void f(struct small **s)
    {
    s = malloc(sizeof(s truct small));
    memset(s, 0, sizeof(struct small));
    s->num = 42;
    }

    main()
    {
    struct big *big_thing;

    big_thing = malloc(sizeof(s truct big));
    memset(&big_thi ng, 0, sizeof(struct big));

    f(&big_thing->small_thing) ;
    printf("%i\n", big_thing->small_thing->n);
    }

    But when I do:
    s->num = 42;
    the compiler fails with error 'request for member 'num' in something
    not an structure or union', and I don't know why.

    I tried this way:

    void f(struct small **s)
    {
    struct small *s_ptr;
    s_ptr->num = 42;
    memcpy(s, &s_ptr, sizeof(struct small));
    }

    I'm not sure, but I think that the second function is unnecessary. So,
    how to fix the first function?

    Thanks.

  • David Resnick

    #2
    Re: error when allocating memory using a pointer inside a structvia a function

    elmafiacs@yahoo .es wrote:
    [color=blue]
    > I need some help with an error I'm getting...
    > Sorry if this is basic stuff, but I'm still a newbie on C programming
    > (working up, though).
    > Also, I'm using gcc as my compiler ('gcc t.c -o t', no strange stuff).
    > Sorry about the long subject, I didn't know how to explain it better...
    >
    > struct small {
    > int num;
    > };
    >
    > struct big {
    > struct small *small_thing;
    > };
    >
    > void f(struct small **s)
    > {
    > s = malloc(sizeof(s truct small));
    > memset(s, 0, sizeof(struct small));
    > s->num = 42;
    > }
    >[/color]

    s is a pointer to a pointer to a struct small, not a pointer
    to a struct small. Accordingly, you want this:

    *s = malloc(sizeof **s);
    memset(*s, 0, sizeof **s);
    (*s)->num = 42;

    And you should check the return value of malloc...

    -David



    -David

    Comment

    • Martin Ambuhl

      #3
      Re: error when allocating memory using a pointer inside a structvia a function

      elmafiacs@yahoo .es wrote:[color=blue]
      > I need some help with an error I'm getting...
      > Sorry if this is basic stuff, but I'm still a newbie on C programming
      > (working up, though).
      > Also, I'm using gcc as my compiler ('gcc t.c -o t', no strange stuff).
      > Sorry about the long subject, I didn't know how to explain it better...
      >
      > struct small {
      > int num;
      > };
      >
      > struct big {
      > struct small *small_thing;
      > };
      >
      > void f(struct small **s)
      > {
      > s = malloc(sizeof(s truct small));
      > memset(s, 0, sizeof(struct small));
      > s->num = 42;
      > }
      >
      > main()
      > {
      > struct big *big_thing;
      >
      > big_thing = malloc(sizeof(s truct big));
      > memset(&big_thi ng, 0, sizeof(struct big));
      >
      > f(&big_thing->small_thing) ;
      > printf("%i\n", big_thing->small_thing->n);
      > }
      >
      > But when I do:
      > s->num = 42;
      > the compiler fails with error 'request for member 'num' in something
      > not an structure or union', and I don't know why.
      >
      > I tried this way:
      >
      > void f(struct small **s)
      > {
      > struct small *s_ptr;
      > s_ptr->num = 42;
      > memcpy(s, &s_ptr, sizeof(struct small));
      > }
      >
      > I'm not sure, but I think that the second function is unnecessary. So,
      > how to fix the first function?
      >
      > Thanks.
      >[/color]

      Please don't post code that is not that which you have actually
      compiled. Here is a start toward fixing your code:
      #include <stdlib.h>
      #include <stdio.h>
      #include <string.h>

      struct small
      {
      int num;
      };

      struct big
      {
      struct small *small_thing;
      };

      void f(struct small **s)
      {
      *s = malloc(sizeof **s);
      /* add code to check that *s != 0 */
      memset(*s, 0, sizeof **s);
      (*s)->num = 42;
      }

      int main(void)
      {
      struct big *big_thing;

      big_thing = malloc(sizeof *big_thing);
      /* add code to check that big_thing != 0 */
      memset(&big_thi ng, 0, sizeof big_thing);

      f(&big_thing->small_thing) ;
      printf("%i\n", big_thing->small_thing->num);
      free(big_thing->small_thing) ;
      free(big_thing) ;
      return 0;
      }



      Comment

      • elmafiacs@yahoo.es

        #4
        Re: error when allocating memory using a pointer inside a struct via a function

        Thanks for the help.

        Comment

        • Al Bowers

          #5
          Re: error when allocating memory using a pointer inside a structvia a function

          Martin Ambuhl wrote:
          [color=blue]
          >
          > Please don't post code that is not that which you have actually
          > compiled. Here is a start toward fixing your code:[/color]

          In addition to compiling, run and testing the code before posting can be
          helpful
          (but not final) in catching additional flaws. For example....
          [color=blue]
          > #include <stdlib.h>
          > #include <stdio.h>
          > #include <string.h>
          >
          > struct small
          > {
          > int num;
          > };
          >
          > struct big
          > {
          > struct small *small_thing;
          > };
          >
          > void f(struct small **s)
          > {
          > *s = malloc(sizeof **s);
          > /* add code to check that *s != 0 */
          > memset(*s, 0, sizeof **s);
          > (*s)->num = 42;
          > }
          >
          > int main(void)
          > {
          > struct big *big_thing;
          >
          > big_thing = malloc(sizeof *big_thing);
          > /* add code to check that big_thing != 0 */
          > memset(&big_thi ng, 0, sizeof big_thing);
          >[/color]
          Running and testing might identify the memset statement flaw
          above. It should be:
          memset(big_thin g, 0 , sizeof big_thing);

          And, as you suggested, code to catch dynamic memory allocations
          with function malloc needs to be added to make execution of the code
          safe. See the example below:
          [color=blue]
          > f(&big_thing->small_thing) ;
          > printf("%i\n", big_thing->small_thing->num);
          > free(big_thing->small_thing) ;
          > free(big_thing) ;
          > return 0;
          > }
          >[/color]
          #include <stdio.h>
          #include <stdlib.h>
          #include <string.h>

          struct small {
          int num;
          };

          struct big {
          struct small *small_thing;
          };

          void f(struct small **s)
          {
          *s = malloc(sizeof(s truct small));
          if(*s)
          {
          memset(*s, 0, sizeof(struct small));
          (*s)->num = 42;
          }
          }

          int main(void)
          {
          struct big *big_thing;

          big_thing = malloc(sizeof(s truct big));
          if(big_thing)
          {
          memset(big_thin g, 0, sizeof(struct big));
          f(&big_thing->small_thing) ;
          if(big_thing->small_thing)
          printf("big_thi ng->small_thing->num = %i\n",
          big_thing->small_thing->num);
          free(big_thing->small_thing) ;
          }
          free(big_thing) ;
          return 0;
          }

          Al Bowers

          Comment

          • Old Wolf

            #6
            Re: error when allocating memory using a pointer inside a struct via a function

            Al Bowers wrote:[color=blue]
            > Martin Ambuhl wrote:[color=green]
            > >
            > > Please don't post code that is not that which you have actually
            > > compiled. Here is a start toward fixing your code:[/color]
            >[color=green]
            > > struct big *big_thing;
            > >
            > > big_thing = malloc(sizeof *big_thing);
            > >
            > > memset(&big_thi ng, 0, sizeof big_thing);[/color]
            >
            > Running and testing might identify the memset statement flaw
            > above. It should be:
            > memset(big_thin g, 0 , sizeof big_thing);
            >[/color]

            1) Running and testing isn't a great way of checking for
            undefined behaviour

            2) A statement: memset(foo, bar, sizeof foo); is wrong, unless
            foo and &foo are the same address (ie. for an array).
            It should be:

            memset(big_thin g, 0, sizeof *big_thing);

            The OP (who has been snipped) had it correct.
            IMHO, even better would be to use calloc instead of malloc.

            Comment

            • Al Bowers

              #7
              Re: error when allocating memory using a pointer inside a structvia a function

              Old Wolf wrote:
              [color=blue]
              >Al Bowers wrote:
              >
              >[color=green]
              >>Martin Ambuhl wrote:
              >>
              >>[color=darkred]
              >>>Please don't post code that is not that which you have actually
              >>>compiled. Here is a start toward fixing your code:
              >>>
              >>>
              >>> struct big *big_thing;
              >>>
              >>> big_thing = malloc(sizeof *big_thing);
              >>>
              >>> memset(&big_thi ng, 0, sizeof big_thing);
              >>>
              >>>[/color]
              >>Running and testing might identify the memset statement flaw
              >>above. It should be:
              >>memset(big_th ing, 0 , sizeof big_thing);
              >>
              >>
              >>[/color]
              >
              >
              >2) A statement: memset(foo, bar, sizeof foo); is wrong, unless
              >foo and &foo are the same address (ie. for an array).
              >It should be:
              >
              > memset(big_thin g, 0, sizeof *big_thing);
              >
              >The OP (who has been snipped) had it correct.
              >
              >
              >[/color]
              I don't think so. The op code was:
              [color=blue]
              > struct big *big_thing;[/color]
              [color=blue]
              > big_thing = malloc(sizeof(s truct big));
              > memset(&big_thi ng, 0, sizeof(struct big));[/color]

              Is that correct?

              I believe it should be:
              memset(big_thin g, 0, sizeof *big_thing);
              or
              memset(big_thin g, 0, sizeof(struct big));

              Comment

              • Old Wolf

                #8
                Re: error when allocating memory using a pointer inside a struct via a function

                Al Bowers wrote:[color=blue]
                > Old Wolf wrote:[color=green]
                > >
                > >It should be:
                > >
                > > memset(big_thin g, 0, sizeof *big_thing);
                > >
                > >The OP (who has been snipped) had it correct.
                > >[/color]
                > I don't think so. The op code was:
                >[color=green]
                > > struct big *big_thing;
                > > big_thing = malloc(sizeof(s truct big));
                > > memset(&big_thi ng, 0, sizeof(struct big));[/color]
                >
                > Is that correct?
                >
                > I believe it should be:
                > memset(big_thin g, 0, sizeof *big_thing);
                > or
                > memset(big_thin g, 0, sizeof(struct big));[/color]

                You're right. I think we got there in the end :)

                Comment

                Working...