C language feature in which a struct may contain as its last member an array with no specified size
C struct data types may end with a flexible array member with no specified size: typedef struct { size_t len; // there must be at least one other data member double arr[]; … Wikipedia
🌐
Wikipedia
en.wikipedia.org › wiki › Flexible_array_member
Flexible array member - Wikipedia
February 7, 2026 - C struct data types may end with a flexible array member with no specified size: typedef struct { size_t len; // there must be at least one other data member double arr[]; // the flexible array member must be last // The compiler may reserve extra padding space here, like it can between struct ...
Top answer
1 of 7
36

It is an accepted "fact" that using goto is poor software engineering practice. That doesn't make it true. There are times when goto is useful, particularly when handling cleanup and when porting from assembler.

Flexible array members strike me as having one main use, off the top of my head, which is mapping legacy data formats like window template formats on RiscOS. They would have been supremely useful for this about 15 years ago, and I'm sure there are still people out there dealing with such things who would find them useful.

If using flexible array members is bad practice, then I suggest that we all go tell the authors of the C99 spec this. I suspect they might have a different answer.

2 of 7
34

No, using flexible array members in C is not bad practice.

This language feature was first standardized in ISO C99, 6.7.2.1 (16). In the following revision, ISO C11, it is specified in Section 6.7.2.1 (18).

You can use them like this:

struct Header {
    size_t n  ;
    long   v[];
};
typedef struct Header Header;

size_t  n = 123; // can dynamically change during program execution
// ...
Header *h = malloc(sizeof(Header) + sizeof(long[n]));
h->n      = n;

Alternatively, you can allocate like this:

Header *h = malloc(sizeof *h + n * sizeof h->v[0]);

Note that sizeof(Header) includes eventual padding bytes, thus, the following allocation is incorrect and may yield a buffer overflow:

Header *h = malloc(sizeof(size_t) + sizeof(long[n])); // invalid!

A struct with a flexible array members reduces the number of allocations for it by 1/2, i.e. instead of 2 allocations for one struct object you need just 1. Meaning less effort and less memory occupied by memory allocator bookkeeping overhead. Furthermore, you save the storage for one additional pointer. Thus, if you have to allocate a large number of such struct instances you measurably improve the runtime and memory usage of your program (by a constant factor).

In contrast to that, using non-standardized constructs for flexible array members that yield undefined behavior (e.g. as in long v[0]; or long v[1];) obviously is bad practice. Thus, as any undefined-behaviour this should be avoided.

Since ISO C99 was released in 1999, more than 20 years ago, striving for ISO C89 compatibility is a weak argument.

🌐
GeeksforGeeks
geeksforgeeks.org › c language › flexible-array-members-structure-c
Flexible Array Members in a structure in C - GeeksforGeeks
August 20, 2024 - Flexible Array Member(FAM) is a feature introduced in the C99 standard of the C programming language.
🌐
Red Hat
developers.redhat.com › articles › 2022 › 09 › 29 › benefits-limitations-flexible-array-members
The benefits and limitations of flexible array members | Red Hat Developer
August 14, 2023 - With the pointer implementation, adding an array element requires an extra load initializing the structure on the heap. Each element added to the array requires two allocations for the object and its data member. The process results in fragmented memory between the object and the area pointed at by data. The C99 standard, section 6.7.2.1.16, defines flexible array members.
🌐
SEI CERT
wiki.sei.cmu.edu › confluence › x › GtcxBQ
DCL38-C. Use the correct syntax when declaring a flexible array member - SEI CERT C Coding Standard - Confluence
Flexible array members are a special type of array in which the last element of a structure with more than one named member has an incomplete array type; that is, the size of the array is not specified explicitly within the structure. This "struct hack" was widely used in practice and supported ...
🌐
GNU
gnu.org › software › c-intro-and-ref › manual › html_node › Flexible-Array-Fields.html
Flexible Array Fields (GNU C Language Manual)
The flexible array has to be the last field in the structure, and there must be other fields before it. Under the C standard, a structure with a flexible array can’t be part of another structure, and can’t be an element of an array.
🌐
Rip Tutorial
riptutorial.com › flexible array members
C Language Tutorial => Flexible Array Members
A structure with at least one member may additionally contain a single array member of unspecified length at the end of the structure. This is called a flexible array member:
🌐
Oracle
docs.oracle.com › cd › E19205-01 › 819-5265 › bjazj › index.html
D.1.8 Flexible Array Members (Sun Studio 12: C User's Guide)
Also known as the “struct hack”. Allows the last member of a struct to be an array of zero length, such as int foo[]; Such a struct is commonly used as the header to access malloced memory. For example, in this structure, struct s { int n; double d[]; } S;, the array, d, is an incomplete ...
Find elsewhere
🌐
TutorialsPoint
tutorialspoint.com › flexible-array-members-in-a-structure-in-c
Flexible Array Members in a Structure in C
A flexible array member is an array inside a structure without a fixed size, and its memory is allocated dynamically at runtime using malloc(), calloc(), or similar functions and it is declared using empty square brackets [].
🌐
YouTube
youtube.com › portfolio courses
Flexible Array Members | C Programming Tutorial - YouTube
How to use flexible array members in structs using C. Source code: https://github.com/portfoliocourses/c-example-code/blob/main/flexible_array_members.c. C...
Published   July 3, 2023
Views   2K
🌐
SEI CERT
wiki.sei.cmu.edu › confluence › display › c › MEM33-C.++Allocate+and+copy+structures+containing+a+flexible+array+member+dynamically
MEM33-C. Allocate and copy structures containing a flexible array member dynamically | CERT Secure Coding
As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member . In most situations, the flexible array member is ignored.
🌐
Medium
light-city.medium.com › understanding-flexible-array-members-in-c-syntax-benefits-and-considerations-094e1b826d83
Understanding Flexible Array Members in C: Syntax, Benefits, and Considerations
January 5, 2024 - In C, a flexible array member is declared by defining the last data member of a structure as an array without a specified length or with a length of 0:
🌐
kees
people.kernel.org › kees › bounded-flexible-arrays-in-c
Bounded Flexible Arrays in C — kees
January 23, 2023 - Such structs therefore fully describe their contents at runtime (and are called “flexible array structures” from here on). In other words, their size can be determined at run-time as: ... Teaching the compiler which struct member is associated with the count of a given flexible array member will allow -fsanitize=bounds and __builtin_dynamic_object_size() to reason about flexible array structure usage as well, covering all arrays in Linux with “known bounds”.
🌐
EmbeTronicX
embetronicx.com › tutorials › p_language › c › flexible-array-member-in-c-fam-array-without-size-in-structure
Flexible Array Member in C (Array without size in structure) ⋆ EmbeTronicX
October 28, 2023 - That flexible array member should be declared as the last member of the structure. The structure must contain at least one more named member before the flexible array member.
Top answer
1 of 1
25

A flexible array member is an array without a specified size. The member has to be the last member of the struct. The actual array size is set when you allocate memory for the struct. Consequently, it only makes sense together with dynamic allocation.

Example:

#define ARRSIZE 10

struct FAM
{
    size_t sz;
    int arr[];   // Must be last struct member
};

struct FAM* fam = malloc(sizeof(struct FAM) + ARRSIZE * sizeof(int));

Now fam->arr is an array with ARRSIZE elements that you can access ussing fam->arr[index].

Further code like:

struct FAM* famA = malloc(sizeof(struct FAM) + 10 * sizeof(int));
struct FAM* famB = malloc(sizeof(struct FAM) + 1000 * sizeof(int));

will give you two pointers of the same type even though the size of the arrays differ.

So why would I use it?

Look at this code

struct FAM
{
    size_t sz;
    int arr[];
};

struct P
{
    size_t sz;
    int* p;
};

int getFAM(struct FAM* f, unsigned long x)
{
    return f->arr[x];
}

int getP(struct P* p, unsigned long x)
{
    return p->p[x];
}

It's two ways of doing "the same". One using a flexible array member, the other using a pointer.

Compiled with gcc -O2 on https://godbolt.org/ I get

which indicates that the flexible array can save you one indirection and thereby generate faster code.

It can be described like: In case of a flexible array member the array has fixed offset from a struct pointer while in case of a pointer-to-int member the array is located where the pointer value says. Consequently, in the first case the compiler can use that "known fixed offset" directly but in the second case the compiler must read the pointer value first and then read the array data.

Note: This example is for one specific system (aka compiler/cpu type). On other systems the result may differ.

🌐
Quentin Santos
qsantos.fr › home › flexible array members: typical c shenanigans
Flexible Array Members: Typical C Shenanigans - Quentin Santos
October 1, 2023 - In summary, embedding a built-in C array is fast, but inconvenient. Using dynamic allocation with malloc is more flexible, but not as fast.
Top answer
1 of 10
38

C++ was first standardized in 1998, so it predates the addition of flexible array members to C (which was new in C99). There was a corrigendum to C++ in 2003, but that didn't add any relevant new features. The next revision of C++ (C++2b) is still under development, and it seems flexible array members still aren't added to it.

2 of 10
36

C++ doesn't support C99 flexible array members at the end of structures, either using an empty index notation or a 0 index notation (barring vendor-specific extensions):

struct blah
{
    int count;
    int foo[];  // not valid C++
};

struct blah
{
    int count;
    int foo[0]; // also not valid C++
};

As far as I know, C++0x will not add this, either.

However, if you size the array to 1 element:

struct blah
{
    int count;
    int foo[1];
};

the code will compile, and work quite well, but it is technically undefined behavior. You can allocate the appropriate memory with an expression that is unlikely to have off-by-one errors:

struct blah* p = (struct blah*) malloc( offsetof(struct blah, foo[desired_number_of_elements]);
if (p) {
    p->count = desired_number_of_elements;

    // initialize your p->foo[] array however appropriate - it has `count`
    // elements (indexable from 0 to count-1)
}

So it's portable between C90, C99 and C++ and works just as well as C99's flexible array members.

Raymond Chen did a nice writeup about this: Why do some structures end with an array of size 1?

Note: In Raymond Chen's article, there's a typo/bug in an example initializing the 'flexible' array. It should read:

for (DWORD Index = 0; Index < NumberOfGroups; Index++) { // note: used '<' , not '='
  TokenGroups->Groups[Index] = ...;
}
🌐
Quora
quora.com › What-are-the-reasons-to-use-a-flexible-array-member-in-a-struct-in-the-C-language
What are the reasons to use a flexible array member in a struct in the C language? - Quora
Answer (1 of 2): What are the reasons to use a flexible array member in a struct in the C language? Buffer handling. “strings” in most languages are one such structure. Change the length of a string, and the string structure changes…