Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: substantially updated recommendation

...

Noncompliant Code Example (Copying)

When using structures with a flexible array member you should never directly copy an instance of the structure. This noncompliant code attempts to replicate a copy an instance of a structure containing a flexible array member (struct flexArrayStruct) by assignment.

Code Block
bgColor#FFcccc
struct flexArrayStruct *flexStructA;
struct flexArrayStruct *flexStructB;
size_t array_size;
size_t i;

/* Initialize array_size */

/* Allocate memory for flexStructA */

/* Allocate memory for flexStructB */

/* Initialize flexStructA */

/* ... */

*flexStructB = *flexStructA;

...

Code Block
bgColor#ccccff
struct flexArrayStruct *flexStructA;
struct flexArrayStruct *flexStructB;
size_t array_size;
size_t i;

/* Initialize array_size */

/* Allocate memory for flexStructA */

/* Allocate memory for flexStructB */

/* Initialize flexStructA */

/* ... */

memcpy(
  flexStructB, 
  flexStructA, 
  (sizeof(struct flexArrayStruct) + sizeof(int) * array_size)
);

In this case the copy is explicit and This compliant solutions ensures that the entire structure, including the flexible array member, is accounted for and correctly copied as well.

Noncompliant Code Example (Function Arguments)

When using structures with a flexible array member you should never directly pass an instance of the structure in as an argument to a function call.   In this noncompliant code, the flexible array structure is passed directly to a function which tries to print the array elements.

Code Block
bgColor#FFcccc
void print_array(struct flexArrayStruct structP) {
  size_t i;

  printfputs("Array is: ");
  for (i = 0; i < structP.num; i++) {
    printf("%d", structP.data[i]);
  }
  printfputs("\n");
}

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 = array_size;

for (i = 0; i < array_size; i++) {
  structP->data[i] = i;
}

print_array(*structP);

The problem with this code is that passing the structure directly to the function actually makes a copy of the structure. This copied fails for the same reason as the previous copy example above.

Compliant Solution (Function Arguments)

...

Code Block
bgColor#ccccff
void print_array(struct flexArrayStruct *structP) {
  size_t i;

  printfputs("Array is: ");
  for (i = 0; i < structP->num; i++) {
    printf("%d", structP->data[i]);
  }
  puts("\n");
}

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 = array_size;

for (i = 0; i < array_size; i++) {
  structP->data[i] = i;
}

print_array(structP);

...