...
Code Block |
---|
|
struct flexArrayStruct *structP;
size_t array_size;
size_t i;
/* Initialize array_size */
/* Space is allocated for the struct */
structP = (struct flexArrayStruct *)
malloc(sizeof(struct flexArrayStruct) + sizeof(int) * array_size);
if (structP == NULL) {
/* Handle malloc failure */
}
structP->num = 0;
/*
* Access data[] as if it had been allocated
* as data[array_size]
*/
for (i = 0; i < array_size; i++) {
structP->data[i] = 1;
}
|
Noncompliant Code Example (
...
When using C99 compliant compilers the one element array hack described above should not be used. In this noncompliant code, just such an array is used where a flexible array member should be used instead.
Code Block |
---|
|
struct flexArrayStruct {
int num;
int data[1];
};
/* ... */
struct flexArrayStruct *flexStruct;
size_t array_size;
size_t i;
/* Initialize array_size */
/* Dynamically allocate memory for the structure */
flexStruct = (struct flexArrayStruct *)
malloc(sizeof(struct flexArrayStruct) + sizeof(int) * (array_size - 1));
if (flexStruct == NULL) {
/* Handle malloc failure */
}
/* Initialize structure */
flexStruct->num = 0;
for (i = 0; i < array_size; i++) {
flexStruct->data[i] = 0;
}
|
Wiki Markup |
---|
As described above, the problem with this code is that strictly speaking the only member that is guaranteed to be valid is {{flexStruct->data\[0\]}}. Unfortunately, when using compilers that do not support the C99 standard in full, or at all, this approach may be the only solution. Microsoft Visual Studio 2005, for example, does not implement the C99 syntax. |
Compliant Solution (Use Flexible Array Members)
Fortunately, when working with C99 compliant compilers, the solution is simple - remove the 1 from the array declaration and adjust the size passed to the malloc() call accordingly. In other words, use flexible array members.
Code Block |
---|
|
struct flexArrayStruct {
int num;
int data[];
};
/* ... */
struct flexArrayStruct *flexStruct;
size_t array_size;
size_t i;
/* Initialize array_size */
/* Dynamically allocate memory for the structure */
flexStruct = (struct flexArrayStruct *)
malloc(sizeof(struct flexArrayStruct) + sizeof(int) * array_size);
if (flexStruct == NULL) {
/* Handle malloc failure */
}
/* Initialize structure */
flexStruct->num = 0;
for (i = 0; i < array_size; i++) {
flexStruct->data[i] = 0;
}
|
Wiki Markup |
---|
In this case, the structure will be treated as if the member {{data\[\]}} had been declared to be {{data\[array_size\].}} |
Noncompliant Code Example (Declaration)
When using structures with a flexible array member you should never directly declare an instance of the structure. In this noncompliant code, a variable of type struct flexArrayStruct is declared.
...