Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6541871
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 25, 20262026-05-25T11:09:27+00:00 2026-05-25T11:09:27+00:00

So C99 blessed the commonly-used flexible array member hack to allow us to make

  • 0

So C99 blessed the commonly-used “flexible array member” hack to allow us to make structs that could be overallocated to suit our size requirements. I suspect it’s perfectly safe on most sane implementations to do this, but is it legal in C to “underallocate” if we know in certain situations that we won’t need some members of a struct?

Abstract Example

Say I have a type:

struct a {
  bool   data_is_x;
  void * data;
  size_t pos;
};

If data_is_x, then the type of data is a type that needs to use the pos member. Otherwise, the functions that work with this struct won’t need the pos member for this particular copy of the struct. Essentially, the struct carries around information about whether or not it has a pos member, and this information will not be changed within the struct‘s lifetime (outside of evil mischief, which will break pretty much anything anyway). Is it safe to say:

struct a *a = malloc(data_is_x ? sizeof(struct a) : offsetof(struct a, pos));

which will allocate space for a pos member only if one is needed? Or does it violate a constraint to use cast space that is too small to a struct pointer, even when you never use the members in question?

Concrete Example

My real-world use case is a bit involved; it’s here mainly so you can understand why I want to do this:

typedef struct {
  size_t size;
  void * data;
  size_t pos;
} mylist;

The code for mylist_create specifies that, for size > 0, data is an array of contiguous data that is size items long (whatever an item may be), but that for size == 0 it is the current node of a doubly-linked list containing the items. All the functions that work with mylists will check whether size == 0. If it does, they’ll handle the data as a linked list with the “current” index being whichever node data points to. If not, they’ll handle the data as an array with the “current” index stored in pos.

Now if size == 0 we don’t really need the pos member, but if size > 0 we will. So my question is, is it legal to do this:

mylist *list = malloc(size ? sizeof(mylist) : offsetof(mylist, pos));

If we guarantee (on penalty of undefined behavior) that, while size == 0, we will never try to (or need to) access the pos member? Or does it say somewhere in the standard that it’s UB to even think about doing this?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-25T11:09:27+00:00Added an answer on May 25, 2026 at 11:09 am

    malloc itself doesn’t care at all how much memory you allocate for a structure, it’s the dereferencing of memory outside the block that is undefined. From C99 6.5.3.2 Address and indirection operators:

    If an invalid value has been assigned to the pointer, the behavior of the unary * operator is undefined.

    And, from 7.20.3 Memory management functions, we find (my italics):

    The pointer returned if the allocation succeeds is suitably aligned so that it may be assigned to a pointer to any type of object and then used to access such an object or an array of such objects in the space allocated (until the space is explicitly deallocated).

    Hence, you can do something like:

    typedef struct { char ch[100]; } ch100;
    ch100 *c = malloc (1);
    

    and, provided you only ever try to do anything with c->ch[0], it’s perfectly acceptable.


    For your specific concrete example, I’m not too sure I’d be that worried, assuming that what you’re concerned about is storage space. If you’re concerned for other reasons, feel free to ignore this bit, especially since the assumptions included within are not mandated by the standard.

    From my understanding, you have a structure:

    typedef struct {
      size_t size;
      void * data;
      size_t pos;
    } mylist;
    

    where you want to use only data where size is 0, and both data and pos where size is greater than 0. This precludes the use of putting data and pos in a union.

    A significant number of malloc implementations will round up your requested space to a multiple of 16 bytes (or some greater power of two) in order to ease memory fragmentation issues. This isn’t required by the standard of course, but it is pretty common.

    Assuming (for example) 32-bit pointers and size_t, your twelve bytes of structure will most likely take up a 16-byte arena header and a 16-byte chunk for the data. This chunk would still be 16 bytes even if you only asked for 8 (ie. without pos).

    If you had 64-bit pointer and size_t types, it might make a difference – 24 bytes with pos and 16 without.

    But even then, unless you’re allocating a lot of these structures, it may not be a problem.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

In C99, you can declare a flexible array member of a struct as such:
What type for array index in C99 should be used? It have to work
The C99 standard allows the creation of flexible array members such as typedef struct
I used to think that in C99, even if the side-effects of functions f
I keep reading about C99 and C++11 and all these totally sweet things that
How universally is the C99 standard supported in today's compilers? I understand that not
I just read that C99 has double_t which should be at least as wide
Paragraph 6.7.3.8 of the C99 spec states If the specification of an array type
To my amazement I just discovered that the C99 stdint.h is missing from MS
I learned today that there are digraphs in C99 and C++. The following is

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.