structs

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

    #1

    structs

    If i create a cruct like so :

    struct test{
    char *var1 ;
    int var2 ;
    short var3 ;
    }

    and i want to allocate it memory, should i allocate enough to hold the max
    amount of data that will go into the char * plus the size of an int plus the
    size of a short or do i need to allocate it more memory than this (the
    reason i was wondering is i dont know how C handles structs in memory and
    how it "binds" the variables together). If this is the case i presume then
    allocating ps.var1 is not neccessary as using ps.var1 will use the memory
    already allocated. Please point me in the right direction if I am not
    getting this.

    Cheers
    Matt


  • Mike Wahler

    #2
    Re: structs

    "Matthew Jakeman" <m.jakeman@nosp am.lancaster.ac .uk> wrote in message
    news:cbv4dn$6tn $1@alliance.lan cs.ac.uk...[color=blue]
    > If i create a cruct like so :
    >
    > struct test{
    > char *var1 ;
    > int var2 ;
    > short var3 ;
    > }[/color]

    Missing semicolon.

    };
    [color=blue]
    >
    > and i want to allocate it memory,[/color]

    Allocate sizeof(struct test) bytes in order to
    provide sufficient memory to store one instance
    of type 'struct test'.
    [color=blue]
    > should i allocate enough to hold the max
    > amount of data that will go into the char *[/color]

    'char *' is a type, whose size is sizeof(char*) bytes.
    That's the maximum amount of 'data' that will 'go into' it.

    If you want your 'char*' pointer to contain the address
    of some other memory, allocate that much, and assign its
    address to the pointer.

    struct test x;
    x.var1 = malloc(how_many _bytes);
    [color=blue]
    > plus the size of an int plus the
    > size of a short[/color]

    No, don't include sizes of other members when allocating
    memory for the pointer member to point to.
    [color=blue]
    >or do i need to allocate it more memory than this (the
    > reason i was wondering is i dont know how C handles structs in memory[/color]

    Get some books! :-)
    See www.accu.org book reviews for recommendations .
    [color=blue]
    >and
    > how it "binds" the variables together).[/color]

    The first member of a struct object always has the same
    address as the struct object itself. The language allows
    'padding' between members, and after the last. Thus the
    'sizeof' a struct type can be, and often is, larger than
    the sum of the sizes of its members.
    [color=blue]
    >If this is the case i presume then
    > allocating ps.var1 is not neccessary as using ps.var1 will use the memory
    > already allocated.[/color]

    Although you didn't state it, I'll assume that 'ps' is an
    object of type 'struct test' (it can't be a pointer, since
    the '.' operator would not be valid to use with it):

    struct test ps;

    The size of 'ps' is at least the sum of the sizes of types
    'char*', 'int', and 'short' (but may be larger). The 'char*'
    type member occupies sizeof(char*) bytes. It's value (an
    address) is meaninless until you assign it one.

    #include <stdlib.h>

    struct test
    {
    char *var1 ;
    int var2 ;
    short var3 ;
    } = {0};

    int main()
    {
    struct test ps; /* occupies sizeof(struct ps) bytes */
    ps.var1 = malloc(100); /* 'ps.var1' contains address of allocated memory
    */
    /* of at least 100 bytes */


    struct test *ptr = malloc(sizeof *ptr);
    /* 'ptr' contains address of allocated memory of */
    /* at least sizeof(struct test) bytes */

    if(ptr)
    ptr->var1 = malloc(20); /* '(*ptr).var1' contains address of
    allocated */
    /* memory of at least 20 bytes */

    /* clean up */
    free(ps.var1);
    free(ptr->var1);
    free(ptr);

    return 0;
    }
    [color=blue]
    >Please point me in the right direction if I am not
    > getting this.[/color]

    OK, I'm pointing you to C books. It would also help if you
    describe exactly what problem you're trying to solve.

    -Mike



    Comment

    • Eric Sosman

      #3
      Re: structs

      Matthew Jakeman wrote:[color=blue]
      > If i create a cruct like so :
      >
      > struct test{
      > char *var1 ;
      > int var2 ;
      > short var3 ;
      > }
      >
      > and i want to allocate it memory, should i allocate enough to hold the max
      > amount of data that will go into the char * plus the size of an int plus the
      > size of a short or do i need to allocate it more memory than this (the
      > reason i was wondering is i dont know how C handles structs in memory and
      > how it "binds" the variables together). If this is the case i presume then
      > allocating ps.var1 is not neccessary as using ps.var1 will use the memory
      > already allocated. Please point me in the right direction if I am not
      > getting this.[/color]

      For an instance of the struct, you need to allocate
      `sizeof(struct test)' bytes. Period.

      If the `var1' element is to point somewhere, there
      must be some memory allocated at that "somewhere. " This
      might be memory you obtain separately from malloc(), or
      it might be a plain old variable, or it might be a string
      literal, or ... `var1' is perfectly happy to point at
      any chunk of memory you feel like. There is no necessary
      "connection " between that memory and the memory for the
      struct instance. Bad ASCII art:

      struct:
      var1 ----------> [elsewhere]
      var2 = 42
      var3 = 042

      If `var1' is supposed to point to some memory that
      is managed as "associated with" or "part of" the struct
      instance, then you might want to allocate one large chunk
      of memory to hold both the struct instance and the stuff
      that `var1' points to. For example, assuming the "stuff"
      is a zero-terminated string:

      struct test *p;
      p = malloc(sizeof(s truct test) + strlen(string) + 1);
      if (p != NULL) {
      strcpy ((char*)(p + 1), string);
      p->var1 = (char*)(p + 1);
      p->var2 = 42;
      p->var3 = 042;
      }

      More bad ASCII art:

      struct:
      var1 ---------+
      var2 = 42 |
      var3 = 042 |
      string <----------+
      copied
      here
      '\0'

      HOWEVER, I do not recommend such shenanigans until your
      grasp of C becomes a bit firmer than it appears to be now:
      Learn to swim before you learn to dive, or you'll likely get
      in over your head. Patience, Grasshopper, patience.

      --
      Eric.Sosman@sun .com

      Comment

      • Russell Hanneken

        #4
        Re: structs

        Matthew Jakeman wrote:[color=blue]
        > If i create a cruct like so :
        >
        > struct test{
        > char *var1 ;
        > int var2 ;
        > short var3 ;
        > }
        >
        > and i want to allocate it memory, should i allocate enough to hold the max
        > amount of data that will go into the char * plus the size of an int plus the
        > size of a short or do i need to allocate it more memory than this[/color]

        You need to allocate memory both for the struct, and the buffer that you
        want var1 to point at. For example:

        struct test *ps = malloc ( sizeof *ps );
        ps->var1 = malloc ( MAX_LENGTH + 1 );

        Of course, you don't have to use malloc to allocate memory:

        struct test s;
        char buffer[MAX_LENGTH + 1] = "";
        s.var1 = buffer;

        --
        Russell Hanneken
        eunaarxra@cbobk .pbz
        Use ROT13 to decode my email address.

        Comment

        • Matthew Jakeman

          #5
          Re: structs

          Thanks for the help guys, when the bugger that has borrowed my C book has
          the decency to give it back ill look it up in there as well!
          Cheers
          Matt

          "Eric Sosman" <Eric.Sosman@su n.com> wrote in message
          news:40E31F43.9 040906@sun.com. ..[color=blue]
          > Matthew Jakeman wrote:[color=green]
          > > If i create a cruct like so :
          > >
          > > struct test{
          > > char *var1 ;
          > > int var2 ;
          > > short var3 ;
          > > }
          > >
          > > and i want to allocate it memory, should i allocate enough to hold the[/color][/color]
          max[color=blue][color=green]
          > > amount of data that will go into the char * plus the size of an int plus[/color][/color]
          the[color=blue][color=green]
          > > size of a short or do i need to allocate it more memory than this (the
          > > reason i was wondering is i dont know how C handles structs in memory[/color][/color]
          and[color=blue][color=green]
          > > how it "binds" the variables together). If this is the case i presume[/color][/color]
          then[color=blue][color=green]
          > > allocating ps.var1 is not neccessary as using ps.var1 will use the[/color][/color]
          memory[color=blue][color=green]
          > > already allocated. Please point me in the right direction if I am not
          > > getting this.[/color]
          >
          > For an instance of the struct, you need to allocate
          > `sizeof(struct test)' bytes. Period.
          >
          > If the `var1' element is to point somewhere, there
          > must be some memory allocated at that "somewhere. " This
          > might be memory you obtain separately from malloc(), or
          > it might be a plain old variable, or it might be a string
          > literal, or ... `var1' is perfectly happy to point at
          > any chunk of memory you feel like. There is no necessary
          > "connection " between that memory and the memory for the
          > struct instance. Bad ASCII art:
          >
          > struct:
          > var1 ----------> [elsewhere]
          > var2 = 42
          > var3 = 042
          >
          > If `var1' is supposed to point to some memory that
          > is managed as "associated with" or "part of" the struct
          > instance, then you might want to allocate one large chunk
          > of memory to hold both the struct instance and the stuff
          > that `var1' points to. For example, assuming the "stuff"
          > is a zero-terminated string:
          >
          > struct test *p;
          > p = malloc(sizeof(s truct test) + strlen(string) + 1);
          > if (p != NULL) {
          > strcpy ((char*)(p + 1), string);
          > p->var1 = (char*)(p + 1);
          > p->var2 = 42;
          > p->var3 = 042;
          > }
          >
          > More bad ASCII art:
          >
          > struct:
          > var1 ---------+
          > var2 = 42 |
          > var3 = 042 |
          > string <----------+
          > copied
          > here
          > '\0'
          >
          > HOWEVER, I do not recommend such shenanigans until your
          > grasp of C becomes a bit firmer than it appears to be now:
          > Learn to swim before you learn to dive, or you'll likely get
          > in over your head. Patience, Grasshopper, patience.
          >
          > --
          > Eric.Sosman@sun .com
          >[/color]


          Comment

          • Gordon Burditt

            #6
            Re: structs

            >struct test{[color=blue]
            > char *var1 ;
            > int var2 ;
            > short var3 ;
            >}
            >
            >and i want to allocate it memory,[/color]

            Then allocate it sizeof(struct test) bytes of memory.
            This does NOT include any memory for var1 to point at.
            If you want memory for that, call malloc() AGAIN.
            [color=blue]
            >should i allocate enough to hold the max
            >amount of data that will go into the char * plus the size of an int plus the
            >size of a short or do i need to allocate it more memory than this (the
            >reason i was wondering is i dont know how C handles structs in memory and
            >how it "binds" the variables together).[/color]

            I don't think the kind of "binding" you are thinking of exists.
            If you want dynamic memory for var1 to point at, allocate it
            (probably with a separate call to malloc(), but it could also
            be in an auto array or a string literal, among other possibilities.
            Pointers can point at things besides dynamically allocated memory).
            [color=blue]
            >If this is the case i presume then
            >allocating ps.var1 is not neccessary as using ps.var1 will use the memory
            >already allocated. Please point me in the right direction if I am not
            >getting this.[/color]

            You need to assign a valid pointer value to ps.var1 that points somewhere,
            before attempting to use it, and to get that valid pointer, you may
            have to call malloc() again..

            Please get your presumer fixed.

            When it comes to dynamically allocated memory (and lots of other things
            in C): You are responsible for DOING IT YOURSELF. You want memory
            for a pointer to point at? Allocate it yourself. You want to free
            it? free() it yourself. C won't do it for you. You want to have
            enough memory to fit your string into? It's your problem to allocate
            enough memory or make sure the string fits in existing allocated memory.
            Failure to do this is how buffer overflow attacks work.

            Gordon L. Burditt

            Comment

            • Martin Ambuhl

              #7
              Re: structs

              Matthew Jakeman wrote:[color=blue]
              > If i create a cruct like so :
              >
              > struct test{
              > char *var1 ;
              > int var2 ;
              > short var3 ;
              > }
              >
              > and i want to allocate it memory, ...[/color]

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

              struct test
              {
              char *var1;
              int var2;
              short var3;
              };

              int main(void)
              {
              struct test *t; /* will point to a struct test */
              struct test v = {.var1 = 0 }; /* is a struct test */
              printf("The sizes reported below will vary by implementation. \n\n");

              printf("The struct test v needs no allocation.\n"
              "It has size %lu, and its members are:\n"
              "v.var1 (a char *), with size %lu\n"
              "v.var2 (an int), with size %lu\n"
              "v.var3 (a short int), with size %lu\n\n",
              (unsigned long) sizeof v,
              (unsigned long) sizeof v.var1,
              (unsigned long) sizeof v.var2,
              (unsigned long) sizeof v.var3);
              if (!(t = malloc(sizeof *t))) { /* attempt to allocate memory */
              fprintf(stderr, "allocation for *t failed, quiting.\n");
              exit(EXIT_FAILU RE);
              }
              printf("The struct test pointer t has size %lu.\n"
              "The space allocated for it to point to (*t) has size %lu\n"
              "Its members are:\n"
              "(*t).var1 (a char *), with size %lu\n"
              "(*t).var2 (an int), with size %lu\n"
              "(*t).var3 (a short int), with size %lu\n",
              (unsigned long) sizeof t,
              (unsigned long) sizeof *t,
              (unsigned long) sizeof(*t).var1 ,
              (unsigned long) sizeof(*t).var2 ,
              (unsigned long) sizeof(*t).var3 );

              free(t); /* release allocated space */
              return 0;
              }


              Comment

              Working...