Thread: Are structs sequential in memory

  1. #1
    Registered User
    Join Date
    Jun 2005
    Posts
    8

    Are structs sequential in memory

    If I define a struct as such:

    Code:
    struct mystruct
    {
        char one;
        char two;
        char three;
        char four;
    };
    Is it guarenteed to be sequential in memory such that I can do an assignment like this:
    Code:
    mystruct s;
    char *p = (char *) &s;
    And I can access and treat the struct as sequential bytes? Will this work, will it always work, and is it even a good idea to do? The reason is for sending large packets of serial data, I would rather format the packet as a struct and then change the struct to an array of bytes to be sent out.

  2. #2
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Most operating systems add padding to structs (to align the struct and a power of 2 (faster)) in memory, some also might order them differently.

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    8
    So this shouldnt be done then. Is there any easy way to format large serial packets so that each byte doesnt have to be masked and packed individually?

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    It's true that in general, there may be padding between struct members. However, in the special case where all the members are the same type, I'm not sure whether the Standard allows it to happen.

    > some also might order them differently.
    Are you sure? I thought there was a guarantee this couldn't happen, but am not absolutely sure.

  5. #5
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Depends on how the OS decides to allocate memory. Although I think your right, they won't reorder the struct. But they can add padding to the end.

    Quote Originally Posted by Supadude View Post
    So this shouldnt be done then. Is there any easy way to format large serial packets so that each byte doesnt have to be masked and packed individually?
    Yes, use a payload sort of scheme.
    Last edited by zacs7; 05-16-2007 at 05:33 AM.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    The order is always as written.

    The gaps between them for padding and alignment however can vary.

    Also, there is never any padding between the start of the struct and the first member.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    Are you sure there's no guarantee that there's no padding if all the struct members are the same type? The reason I ask is that such a struct could be treated like an array of the given type (for example the OP's example could be treated like an array of 4 chars) and array elements are guaranteed to be contiguous in memory. It seems surprising that the Standard wouldn't bother to give a guarantee if it's so easy to do.

  8. #8
    Registered User kryptkat's Avatar
    Join Date
    Dec 2002
    Posts
    638
    how do you find out how much padding there is?

  9. #9
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    Quote Originally Posted by kryptkat View Post
    how do you find out how much padding there is?
    You can print the member addresses:
    Code:
    #include <stdio.h>
    
    struct A {
      char x;
      int y;
    };
    
    int main(void)
    {
      struct A a;
      printf("address of a.x is %p\n", &a.x);
      printf("address of a.y is %p\n", &a.y);
      return 0;
    }
    Output on my box:

    address of a.x is 0xbf9b716c
    address of a.y is 0xbf9b7170

    The difference is 4 so there are 3 bytes of padding between a.x and a.y.

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Supadude View Post
    And I can access and treat the struct as sequential bytes? Will this work, will it always work, and is it even a good idea to do? The reason is for sending large packets of serial data, I would rather format the packet as a struct and then change the struct to an array of bytes to be sent out.
    If you are willing to restrict yourself to a specific compiler or set of compilers, there are usually compiler-specific (read "non-portable") ways to tell the compiler to pack the struct as tight as possible -- no padding between members or at the end of the struct.

    Portably, the only thing you can rely on is that the order of the struct members in memory is generally the same as the order they are defined in the struct, although padding may be added between members. So in general you can't assume a struct is precisely equivalent to an unpadded sequence of bytes.

    Rather than invoke compiler-specific directives, I would recommend just biting (byting?) the bullet and writing some basic routines to do PORTABLE input/output of various data types. Write a function which handles chars (trivial), a function for 2 byte quantities (usually shorts, but not guaranteed), a function for 4 byte quantities, etc. It is possible to make these macros instead of functions, but with caveats.

    As always, the three main issues are packing/padding, endianness, and signed integer representation. The general "science" of how to portably input and output binary data structures is called "marshaling."

  11. #11
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by kryptkat View Post
    how do you find out how much padding there is?
    use sizeof struct - sum sizeof members
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  12. #12
    Registered User
    Join Date
    Jun 2005
    Posts
    8
    Quote Originally Posted by zacs7 View Post
    Yes, use a payload sort of scheme.
    Could you elaborate on this?

  13. #13
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    Not sure how portable this is (I know that it works for 16-bit DOS, Linux, and Windows XX):

    __attribute__((aligned (1),packed))

    Will align your struct at 1 byte offsets.

  14. #14
    C maniac
    Join Date
    Aug 2004
    Location
    Cyberwarping to Middle Earth
    Posts
    154
    Depends on how the OS decides to allocate memory. Although I think your right, they won't reorder the struct. But they can add padding to the end.
    If the OS supports the Berkley Network Package (sockets) is has do to it in the same order, always, because of one of the structs (can't remember which, i'll look at beej).

    EDIT: It's struct sockaddr, heres the link: http://beej.us/guide/bgnet/output/ht...t.html#structs

  15. #15
    Crazy Fool Perspective's Avatar
    Join Date
    Jan 2003
    Location
    Canada
    Posts
    2,640
    "I have a bunch of elements of the same type that I want to store in contiguous memory..."

    I don't understand why this converstation is even about structs, use an array.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Mutex and Shared Memory Segment Questions.
    By MadDog in forum Linux Programming
    Replies: 14
    Last Post: 06-20-2010, 04:04 AM
  2. Replies: 7
    Last Post: 02-06-2009, 12:27 PM
  3. Pointer's
    By xlordt in forum C Programming
    Replies: 13
    Last Post: 10-14-2003, 02:15 PM
  4. Managing shared memory lookups
    By clancyPC in forum Linux Programming
    Replies: 0
    Last Post: 10-08-2003, 04:44 AM
  5. Accessing Video Memory Information...need help
    By KneeLess in forum C++ Programming
    Replies: 8
    Last Post: 08-24-2003, 03:53 PM