Thread: Struct array size

  1. #1
    Registered User
    Join Date
    Feb 2008
    Posts
    58

    Question Struct array size

    Hi

    I have a Struct that contains a number of values, one of these values is an array that I want to define the size of later in my application.

    Code:
    typedef struct
    {
    uint8_t	  address;
    uint8_t	  rxAddress;
    uint8_t	  type;
    uint8_t 	  payload[54];  // <- This one here
    } PACK packet_t;
    It can be one of two sizes, either 54 (as shown above) or 9, and I cannot work out a way to allocate it during the init of my application. I have tried using malloc to allocate the space needed, it does not complain however I don’t believe the size is correct as when I set it to 56 I get array overflows...

    Has anyone got any clever ideas?

    thanks

    David

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    typedef struct
    {
    uint8_t	  address;
    uint8_t	  rxAddress;
    uint8_t	  type;
    uint8_t 	  payload[1];  // <- This one here
    } PACK packet_t;
    The above definition [note 54 changed to 1] and the following:
    Code:
    packet_t *allocatePacket(bool has54payload)
    {
       packet_t *pkt;
       size_t size = 9;
       if (has54payload) size = 54;
       pkt = malloc(sizeof(packet_t) + size - 1);   // -1 because we already have 1 element in the struct. 
       return pkt;
    }
    Some compilers support
    Code:
        ...
        uint8_t 	  payload[0]; 
        ...
    In which case you could remove the -1 in the malloc() call.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User Kernel Sanders's Avatar
    Join Date
    Aug 2008
    Posts
    61
    Quote Originally Posted by matsp View Post
    Code:
    typedef struct
    {
    uint8_t	  address;
    uint8_t	  rxAddress;
    uint8_t	  type;
    uint8_t 	  payload[1];  // <- This one here
    } PACK packet_t;
    The above definition [note 54 changed to 1] and the following:
    Code:
    packet_t *allocatePacket(bool has54payload)
    {
       packet_t *pkt;
       size_t size = 9;
       if (has54payload) size = 54;
       pkt = malloc(sizeof(packet_t) + size - 1);   // -1 because we already have 1 element in the struct. 
       return pkt;
    }
    Some compilers support
    Code:
        ...
        uint8_t 	  payload[0]; 
        ...
    In which case you could remove the -1 in the malloc() call.

    --
    Mats
    That's damn clever. I'm impressed

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Kernel Sanders View Post
    That's damn clever. I'm impressed
    I must admit that I didn't invent that method - it was used in OSE when I started working for Enea Data in the early 1990's. And it's a fairly standard pattern (I have seen it several places since then). It works as long as the packet ENDS with the variable part. Otherwise it's much harder to solve.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Feb 2008
    Posts
    58
    wow - thank you

  6. #6
    Registered User
    Join Date
    Jul 2008
    Posts
    133
    Quote Originally Posted by matsp View Post
    I must admit that I didn't invent that method - it was used in OSE when I started working for Enea Data in the early 1990's. And it's a fairly standard pattern (I have seen it several places since then). It works as long as the packet ENDS with the variable part. Otherwise it's much harder to solve.

    --
    Mats
    Now, I'm impressed

  7. #7
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    Out of curiosity is there any particular reason why you would use:
    Code:
    uint8_t payload[1];
    instead of
    Code:
    uint8_t* payload;
    ?

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by mike_g View Post
    Out of curiosity is there any particular reason why you would use:
    Code:
    uint8_t payload[1];
    instead of
    Code:
    uint8_t* payload;
    ?
    Because that's then not part of the SAME chunk of memory - the payload would be a pointer to another piece of memory, which means that the sending routine would have to keep track of the size of the header and the packet itself in separate sections. Many times, you want ONE lump of memory to send [particularly for the low-level driver that doesn't even care about the protocol - you just package up some data into a packet and send it to the low-level driver that sends the whole thing - if you have multiple chunks of memory, the low-level driver must have a list of different items to transmit. Makes the driver a bit more complex].

    Edit: Also, having two different parts of memory makes the receiving end more complex, as the low-level driver will have to call malloc (or similar) twice rather than once for the packet.

    --
    Mats
    Last edited by matsp; 08-19-2008 at 09:13 AM.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    Oh I see, thanks.

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    It's such a useful technique that is has been blessed by C99
    http://www.comeaucomputing.com/techt...flexiblearrays
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 16
    Last Post: 05-29-2009, 07:25 PM
  2. Replies: 16
    Last Post: 10-29-2006, 05:04 AM
  3. Passing pointers between functions
    By heygirls_uk in forum C Programming
    Replies: 5
    Last Post: 01-09-2004, 06:58 PM
  4. Bi-Directional Linked Lists
    By Thantos in forum C Programming
    Replies: 6
    Last Post: 12-11-2003, 10:24 AM
  5. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM