C struct data types may end with a flexible array member[1] 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 members
} DoubleArray;

Typically, such structures serve as the header in a larger, variable memory allocation:

// see section on size and padding
DoubleArray* darray = malloc(sizeof(DoubleArray) + ... * sizeof(double));
darray->len = ...;
for (int i = 0; i < darray->len; i++) {
    darray->arr[i] = ...; // transparently uses the right type (double)
}

Effect on struct size and padding

edit

The sizeof operator on such a struct gives the size of the structure as if the flexible array member were empty. This may include padding added to accommodate the flexible member; the compiler is also free to re-use such padding as part of the array itself.[2]

It is common to allocate sizeof(struct) + array_len * sizeof(array element) bytes.

This is not wrong, but it may allocate a few more bytes than necessary: the compiler may be re-purposing some of the padding that is included in sizeof(struct). Should this be a concern, macros are available[3] to compute the minimum size while ensuring that the compiler's padding is not disrupted.

As the array may start in the padding before the end of the structure, its content should always be accessed via indexing (arr[i]) or offsetof, not sizeof.

Availability

edit

Flexible array members were officially standardized in C99.[4] In practice, compilers (e.g., GCC,[5] MSVC[6]) provided them well before C99 was standardized.

Flexible array members are not officially part of C++, but language extensions[7] are widely available.

References

edit
  1. ^ "Lesser known C features". Retrieved December 30, 2014.
  2. ^ "flexible array member". Jens Gustedt's Blog. March 14, 2011. Retrieved October 9, 2018.
  3. ^ "P99: Flexible array members". p99.gforge.inria.fr. Retrieved October 9, 2018.
  4. ^ C99 section §6.7.2.1, item 16, page 103, https://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
  5. ^ "Zero Length - Using the GNU Compiler Collection (GCC)". Retrieved December 30, 2014.
  6. ^ "Structure Declarations". Microsoft. Retrieved April 25, 2020.
  7. ^ E.g., "Arrays (C++)". Microsoft. Retrieved April 25, 2020. A zero-sized array is legal only when the array is the last field in a struct or union and when the Microsoft extensions (/Ze) are enabled.

📚 Artikel Terkait di Wikipedia

Sizeof

a[]; // Flexible array member; must be last element of struct } FlexibleArray; int main(int argc, char* argv[]) { printf("sizeof(FlexibleArray) == %zu\n"

Struct (C programming language)

efficient at run-time. Since C99, a struct may also end with a flexible array member. Structs can be composed of other structs: struct Date { int year;

Compatibility of C and C++

arrays (complex numbers and variable length arrays are designated as optional extensions in C11), flexible array members, the restrict keyword, array

C data types

efficient at run-time. Since C99, a struct may also end with a flexible array member. Functions may take a struct as a parameter by value, but this is

C (programming language)

complex type to represent complex numbers), variable-length arrays and flexible array members, improved support for IEEE 754 floating point, support for

C99

variable-length arrays (although subsequently relegated in C11 to a conditional feature that implementations are not required to support) flexible array members support

Roll Out Solar Array

The Roll Out Solar Array (ROSA) and its larger version ISS Roll Out Solar Array (iROSA) are lightweight, flexible power sources for spacecraft designed

NTFS reparse point

ReparseDataLength; uint16_t Reserved; uint8_t DataBuffer[]; // flexible array member } The reparse tag is unique to each type of reparse point. It defines