Memory alignment

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

    Memory alignment

    typedef struct some_struct
    {
    int i;
    short k,
    int m;
    char s[1];
    } some_struct_t;

    Assuming 16 bit or 32-bit alignment, can I assume that
    s always gets 4 or 8 bytes of allocation due to padding
    in the following? (I.e. s is either 4 or 8 characters long)

    some_struct_t *my_struct;
    my_struct = malloc(sizeof(s ome_struct_t));

    BTW, this is on a PowerPC architecture.

    /Why Tea
  • Fred

    #2
    Re: Memory alignment

    On Oct 3, 10:47 am, Why Tea <ytl...@gmail.c omwrote:
    typedef struct some_struct
    {
        int i;
        short k,
        int m;
        char s[1];
    >
    } some_struct_t;
    >
    Assuming 16 bit or 32-bit alignment, can I assume that
    s always gets 4 or 8 bytes of allocation due to padding
    in the following? (I.e. s is either 4 or 8 characters long)
    >
    some_struct_t *my_struct;
    my_struct = malloc(sizeof(s ome_struct_t));
    >
    BTW, this is on a PowerPC architecture.
    >
    s will get one byte of space.
    The struct itself may or may not get additional bytes or padding,
    but writing to s[1] is an error.
    --
    Fred Kleinschmidt.

    Comment

    • Why Tea

      #3
      Re: Memory alignment

      On Oct 3, 12:18 pm, Fred <fred.l.kleinsc hm...@boeing.co mwrote:
      On Oct 3, 10:47 am, Why Tea <ytl...@gmail.c omwrote:
      >
      >
      >
      typedef struct some_struct
      {
          int i;
          short k,
          int m;
          char s[1];
      >
      } some_struct_t;
      >
      Assuming 16 bit or 32-bit alignment, can I assume that
      s always gets 4 or 8 bytes of allocation due to padding
      in the following? (I.e. s is either 4 or 8 characters long)
      >
      some_struct_t *my_struct;
      my_struct = malloc(sizeof(s ome_struct_t));
      >
      BTW, this is on a PowerPC architecture.
      >
      s will get one byte of space.
      The struct itself may or may not get additional bytes or padding,
      Why not if alignment is done at 16 or 32 bit boundary?
      but writing to s[1] is an error.
      But strcpy(my->struct->s, "AB"); is OK if there is
      padding. Isn't it not? Please go easy on me here.
      I just want to understand how this really works...

      Comment

      • Antoninus Twink

        #4
        Re: Memory alignment

        On 3 Oct 2008 at 18:33, Why Tea wrote:
        typedef struct some_struct
        {
            int i;
            short k,
            int m;
            char s[1];
        } some_struct_t;
        >
        But strcpy(my->struct->s, "AB"); is OK if there is
        padding. Isn't it not? Please go easy on me here.
        I just want to understand how this really works...
        Yes, of course, if there are two or more padding bytes at the end of the
        struct then that's your memory to write to, whether it's on the stack if
        my_struct is an automatic variable, or on the heap if you got the memory
        from malloc().

        You should be aware that the regulars here aren't interested in your
        wish for a pragmatic answer that's true in practise: they'll just
        bombard you with hypothetical answers that are true in theory.

        Comment

        • danmath06@gmail.com

          #5
          Re: Memory alignment

          On Oct 3, 2:47 pm, Why Tea <ytl...@gmail.c omwrote:
          typedef struct some_struct
          {
          int i;
          short k,
          int m;
          char s[1];
          >
          } some_struct_t;
          >
          Assuming 16 bit or 32-bit alignment, can I assume that
          s always gets 4 or 8 bytes of allocation due to padding
          in the following? (I.e. s is either 4 or 8 characters long)
          Each element in the structure has the size you specified in the
          declaration, padding adds space between elements to adjust alignment
          or at the end. s has only one character.

          For example there might be 2 bytes of space between k and m so that m
          starts on an 32bit alignes address. You could avoid this by keeping
          the integers together:

          typedef struct some_struct
          {
          int i;
          int m;
          short k,
          char s[1];

          } some_struct_t;

          This might result in only one extra byte at the end.

          You can always use sizeof(struct some_struct) to know the size of the
          structure and guess how many bytes were added as padding.
          offsetof(struct some_struct, s) will return the offset of s in the
          structure (you will need: #include <stddef.h>). You can use offsetof()
          to find out the position of every element in the struct and determine
          where the struct has been padded.








          Comment

          • danmath06@gmail.com

            #6
            Re: Memory alignment

            But strcpy(my->struct->s, "AB"); is OK if there is
            padding. Isn't it not? Please go easy on me here.
            I just want to understand how this really works...
            It will, but if you add a new elemnt at the end of the structure later
            on in might not, you might overwrite the next element.

            Why would you want to declare a 1 char array to store 2 anyway?

            Comment

            • Why Tea

              #7
              Re: Memory alignment

              On Oct 3, 12:48 pm, danmat...@gmail .com wrote:
              But strcpy(my->struct->s, "AB"); is OK if there is
              padding. Isn't it not? Please go easy on me here.
              I just want to understand how this really works...
              >
              It will, but if you add a new elemnt at the end of the structure later
              on in might not, you might overwrite the next element.
              >
              Why would you want to declare a 1 char array to store 2 anyway?
              Good question. This is found in some real embedded
              code to make more efficient of the memory. As I understood
              it, the last s[1] is just a placeholder as you can
              allocate more memory when needed. For example:

              my_struct = malloc(sizeof(m y_struct_t) + MY_PAYLOAD_STRI NG_SIZE);

              The same my_struct_t is used throughout the code for
              signal sending. If s[] is used to carry binary data, the
              size is specified by an int preceding s[]. I'd be
              interested to hear comments from the experts about
              this approach.

              Comment

              • Ian Collins

                #8
                Re: Memory alignment

                Why Tea wrote:
                On Oct 3, 12:48 pm, danmat...@gmail .com wrote:
                >>But strcpy(my->struct->s, "AB"); is OK if there is
                >>padding. Isn't it not? Please go easy on me here.
                >>I just want to understand how this really works...
                >It will, but if you add a new elemnt at the end of the structure later
                >on in might not, you might overwrite the next element.
                >>
                >Why would you want to declare a 1 char array to store 2 anyway?
                >
                Good question. This is found in some real embedded
                code to make more efficient of the memory. As I understood
                it, the last s[1] is just a placeholder as you can
                allocate more memory when needed. For example:
                >
                my_struct = malloc(sizeof(m y_struct_t) + MY_PAYLOAD_STRI NG_SIZE);
                >
                The same my_struct_t is used throughout the code for
                signal sending. If s[] is used to carry binary data, the
                size is specified by an int preceding s[]. I'd be
                interested to hear comments from the experts about
                this approach.
                There isn't much to say, it's known as the "struct hack" and fairly
                common. There's probably some decent reference on the web if you google
                for it.

                --
                Ian Collins.

                Comment

                • Eric Sosman

                  #9
                  Re: Memory alignment

                  Why Tea wrote:
                  On Oct 3, 12:48 pm, danmat...@gmail .com wrote:
                  >>But strcpy(my->struct->s, "AB"); is OK if there is
                  >>padding. Isn't it not? Please go easy on me here.
                  >>I just want to understand how this really works...
                  >It will, but if you add a new elemnt at the end of the structure later
                  >on in might not, you might overwrite the next element.
                  >>
                  >Why would you want to declare a 1 char array to store 2 anyway?
                  >
                  Good question. This is found in some real embedded
                  code to make more efficient of the memory. As I understood
                  it, the last s[1] is just a placeholder as you can
                  allocate more memory when needed. For example:
                  >
                  my_struct = malloc(sizeof(m y_struct_t) + MY_PAYLOAD_STRI NG_SIZE);
                  >
                  The same my_struct_t is used throughout the code for
                  signal sending. If s[] is used to carry binary data, the
                  size is specified by an int preceding s[]. I'd be
                  interested to hear comments from the experts about
                  this approach.
                  You're full of questions, Why Tea, and that's a good thing.
                  But has it occurred to you that other people have asked some of
                  these same questions? Has it occurred to you to look for a FAQ
                  at some likely-sounding site like, oh, <http://www.c-faq.com/>?
                  If you get lucky and find some useful material at such a site,
                  I'd suggest not limiting yourself only to reading Question 2.6
                  (for instance), but perusing some of the others as well.

                  --
                  Eric.Sosman@sun .com

                  Comment

                  • Ben Bacarisse

                    #10
                    Re: Memory alignment

                    Why Tea <ytlim1@gmail.c omwrites:
                    On Oct 3, 12:48 pm, danmat...@gmail .com wrote:
                    But strcpy(my->struct->s, "AB"); is OK if there is
                    padding. Isn't it not? Please go easy on me here.
                    I just want to understand how this really works...
                    >>
                    >It will, but if you add a new elemnt at the end of the structure later
                    >on in might not, you might overwrite the next element.
                    >>
                    >Why would you want to declare a 1 char array to store 2 anyway?
                    >
                    Good question. This is found in some real embedded
                    code to make more efficient of the memory. As I understood
                    it, the last s[1] is just a placeholder as you can
                    allocate more memory when needed. For example:
                    >
                    my_struct = malloc(sizeof(m y_struct_t) + MY_PAYLOAD_STRI NG_SIZE);
                    This is called the "struct hack". It has been formalised in C99 so if
                    you can use C99 then all will be well.
                    The same my_struct_t is used throughout the code for
                    signal sending. If s[] is used to carry binary data, the
                    size is specified by an int preceding s[]. I'd be
                    interested to hear comments from the experts about
                    this approach.
                    It is considered to be "a bit dodgy" (that is the technical term) but
                    it generally works. I am not sure there is really much more to say
                    about it though I get the feeling I will be proved very much wrong
                    about that!

                    --
                    Ben.

                    Comment

                    • Lowell Gilbert

                      #11
                      Re: Memory alignment

                      Why Tea <ytlim1@gmail.c omwrites:
                      On Oct 3, 12:48 pm, danmat...@gmail .com wrote:
                      But strcpy(my->struct->s, "AB"); is OK if there is
                      padding. Isn't it not? Please go easy on me here.
                      I just want to understand how this really works...
                      >>
                      >It will, but if you add a new elemnt at the end of the structure later
                      >on in might not, you might overwrite the next element.
                      >>
                      >Why would you want to declare a 1 char array to store 2 anyway?
                      >
                      Good question. This is found in some real embedded
                      code to make more efficient of the memory. As I understood
                      it, the last s[1] is just a placeholder as you can
                      allocate more memory when needed. For example:
                      >
                      my_struct = malloc(sizeof(m y_struct_t) + MY_PAYLOAD_STRI NG_SIZE);
                      or even more likely, something more like
                      my_struct = malloc(sizeof(m y_struct_t) + strlen(my->struct->s));
                      The same my_struct_t is used throughout the code for
                      signal sending. If s[] is used to carry binary data, the
                      size is specified by an int preceding s[]. I'd be
                      interested to hear comments from the experts about
                      this approach.
                      But that's different, because you allocated more space. Even without
                      worrying about the alignments, you *know* that the structure is big
                      enough for the data you're putting into it. There's no reason to play
                      around with the padding; just allocate the space you need.

                      --
                      Lowell Gilbert, embedded/networking software engineer

                      Comment

                      • Eric Sosman

                        #12
                        Re: Memory alignment

                        Why Tea wrote:
                        On Oct 3, 12:18 pm, Fred <fred.l.kleinsc hm...@boeing.co mwrote:
                        >On Oct 3, 10:47 am, Why Tea <ytl...@gmail.c omwrote:
                        >>
                        >>
                        >>
                        >>typedef struct some_struct
                        >>{
                        >> int i;
                        >> short k,
                        >> int m;
                        >> char s[1];
                        >>} some_struct_t;
                        >>Assuming 16 bit or 32-bit alignment, can I assume that
                        >>s always gets 4 or 8 bytes of allocation due to padding
                        >>in the following? (I.e. s is either 4 or 8 characters long)
                        >>some_struct _t *my_struct;
                        >>my_struct = malloc(sizeof(s ome_struct_t));
                        >>BTW, this is on a PowerPC architecture.
                        >s will get one byte of space.
                        >The struct itself may or may not get additional bytes or padding,
                        >
                        Why not if alignment is done at 16 or 32 bit boundary?
                        Because you don't know for sure what the alignment
                        requirement is.
                        >but writing to s[1] is an error.
                        >
                        But strcpy(my->struct->s, "AB"); is OK if there is
                        padding. Isn't it not? Please go easy on me here.
                        I just want to understand how this really works...
                        It's not OK at all: It tries to cram three bytes into a
                        one-byte space. If the struct has two or more padding bytes
                        at the end you might get away with it. If the struct has no
                        padding you might get away with it if it just happens that
                        there's nothing important right after the struct. The "What?
                        Me worry?" school of programming has no lack of adherents;
                        you can read all about them in CERT bulletins.

                        When you go home tonight, get yourself a cane or a medium-
                        sized tree branch or an umbrella or something of that sort.
                        Close your eyes before you walk through the door, and keep
                        them closed while walking several paces into the room. Then
                        swing the cane or whatever vigorously about yourself, striking
                        in every direction, including overhead. It's possible that
                        you won't smash anything ...

                        --
                        Eric.Sosman@sun .com

                        Comment

                        • Why Tea

                          #13
                          Re: Memory alignment

                          On Oct 3, 1:47 pm, Eric Sosman <Eric.Sos...@su n.comwrote:
                          Why Tea wrote:
                          On Oct 3, 12:48 pm, danmat...@gmail .com wrote:
                          >But strcpy(my->struct->s, "AB"); is OK if there is
                          >padding. Isn't it not? Please go easy on me here.
                          >I just want to understand how this really works...
                          It will, but if you add a new elemnt at the end of the structure later
                          on in might not, you might overwrite the next element.
                          >
                          Why would you want to declare a 1 char array to store 2 anyway?
                          >
                          Good question. This is found in some real embedded
                          code to make more efficient of the memory. As I understood
                          it, the last s[1] is just a placeholder as you can
                          allocate more memory when needed. For example:
                          >
                          my_struct = malloc(sizeof(m y_struct_t) + MY_PAYLOAD_STRI NG_SIZE);
                          >
                          The same my_struct_t is used throughout the code for
                          signal sending. If s[] is used to carry binary data, the
                          size is specified by an int preceding s[]. I'd be
                          interested to hear comments from the experts about
                          this approach.
                          >
                               You're full of questions, Why Tea, and that's a good thing.
                          But has it occurred to you that other people have asked some of
                          these same questions?  Has it occurred to you to look for a FAQ
                          at some likely-sounding site like, oh, <http://www.c-faq.com/>?
                          If you get lucky and find some useful material at such a site,
                          I'd suggest not limiting yourself only to reading Question 2.6
                          (for instance), but perusing some of the others as well.
                          >
                          --
                          Eric.Sos...@sun .com
                          Eric, thanks for the gentle nudge. I did google, but I didn't
                          know it was called "struct hack". It's hard to find the
                          right thing if you don't know the right term. Thanks to all
                          who took the time to reply.

                          Comment

                          • jameskuyper@verizon.net

                            #14
                            Re: Memory alignment

                            Why Tea wrote:
                            On Oct 3, 12:48�pm, danmat...@gmail .com wrote:
                            But strcpy(my->struct->s, "AB"); is OK if there is
                            padding. Isn't it not? Please go easy on me here.
                            I just want to understand how this really works...
                            It will, but if you add a new elemnt at the end of the structure later
                            on in might not, you might overwrite the next element.

                            Why would you want to declare a 1 char array to store 2 anyway?
                            >
                            Good question. This is found in some real embedded
                            code to make more efficient of the memory. As I understood
                            it, the last s[1] is just a placeholder as you can
                            allocate more memory when needed. For example:
                            >
                            my_struct = malloc(sizeof(m y_struct_t) + MY_PAYLOAD_STRI NG_SIZE);
                            >
                            The same my_struct_t is used throughout the code for
                            signal sending. If s[] is used to carry binary data, the
                            size is specified by an int preceding s[]. I'd be
                            interested to hear comments from the experts about
                            this approach.
                            In C90, this was technically illegal, but as a practical matter it
                            worked on most (all?) implementations . It was sufficiently useful that
                            a modified version of the concept was added as an extension to many
                            complilers, but with the difference that the array was declared with a
                            size of 0, rather than 1. In C99, a modified version of the concept
                            was made finally standardized, under the name "flexible arrays". For
                            the C99 version, you should use:

                            typedef struct some_struct
                            {
                            int i;
                            short k,
                            int m;
                            char s[];
                            } some_struct_t;

                            With all three versions of this concept, it's required that the array
                            be declared at the end of the structure. The best way to handle the
                            allocation is as follows:

                            my_struct = malloc(offsetof (some_struct_t, s) +
                            MY_PAYLOAD_STRI NG_SIZE*sizeof my_struct.s[0]);

                            Using offsetof() rather than sizeof() makes a difference for the C90
                            version, because the size of the struct includes enough room for one
                            element of the array, whereas offsetof() does not. That means that
                            with sizeof you'd be reserving room for at least 1 more array element
                            than you need to (unless MY_PAYLOAD_STRI NG_SIZE does not include the
                            terminating null character). For C99 sizeof(some_str uct_t) and
                            offsetof(some_s truct_t, s) should give the same result.
                            Using sizeof mystruct.s[0] protects against the possibility that you
                            might change the element type of s. It also helps makes it easier to
                            verify that allocation is correct. If the length of the flexible array
                            is stored in the struct, as is usually the case, I'd recommend filling
                            in that member, and using the value of that member instead of
                            MY_PAYLOAD_STRI NG_SIZE. Again, the main advantage of this is that it
                            makes it easier for a reader to verify that the code is correct.

                            Comment

                            • Keith Thompson

                              #15
                              Re: Memory alignment

                              Why Tea <ytlim1@gmail.c omwrites:
                              typedef struct some_struct
                              {
                              int i;
                              short k,
                              int m;
                              char s[1];
                              } some_struct_t;
                              >
                              Assuming 16 bit or 32-bit alignment, can I assume that
                              s always gets 4 or 8 bytes of allocation due to padding
                              in the following? (I.e. s is either 4 or 8 characters long)
                              >
                              some_struct_t *my_struct;
                              my_struct = malloc(sizeof(s ome_struct_t));
                              >
                              BTW, this is on a PowerPC architecture.
                              You can assume that s itself will be allocated exactly 1 byte. Any
                              padding following it is part of the struct, but not part of s.

                              In general, compilers are allowed to insert arbitrary padding between
                              members or after the last member of a struct. The purpose of this
                              padding is generally to meet alignment requirements, but the standard
                              doesn't place any restrictions on how little or how much padding is
                              used, as long as the members can be accessed.

                              So no, you can't portably make any assumptions about how much padding
                              is added after s. But you generally shouldn't need to. If you'll let
                              us know what you're trying to do, we can probably help you do it
                              *without* making any (or too many) non-portable assumptions. If
                              you're trying to use the "struct hack", see question 2.6 in the
                              comp.lang.c FAQ, <http://c-faq.com/>.

                              --
                              Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                              Nokia
                              "We must do something. This is something. Therefore, we must do this."
                              -- Antony Jay and Jonathan Lynn, "Yes Minister"

                              Comment

                              Working...