Описание
Неправильное употребление структуры с участником массива с переменными границами происходит когда:
Вы задаете объект с членом массива с переменными границами неизвестного размера во время компиляции.
Вы делаете присвоение между структурами с участником массива с переменными границами, не используя memcpy()
или подобную функцию.
Вы используете структуру с участником массива с переменными границами в качестве аргумента к функции и передаете аргумент значением.
Ваша функция возвращает структуру с участником массива с переменными границами.
Участник массива с переменными границами не имеет никакого заданного размера массивов и является последним элементом структуры по крайней мере с двумя именованными участниками.
Риск
Если размер участника массива с переменными границами не задан, он проигнорирован при выделении памяти для содержания структуры. Доступ к такой структуре имеет неопределенное поведение.
Фиксация
Используйте malloc()
или подобную функцию, чтобы выделить память для структуры с участником массива с переменными границами.
Используйте memcpy()
или подобную функцию, чтобы скопировать структуру с участником массива с переменными границами.
Передайте структуру с участником массива с переменными границами как аргумент функции указателем.
Пример - структура, пройден значением, чтобы функционировать
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
struct example_struct
{
size_t num;
int data[];
};
extern void arg_by_value(struct example_struct s);
void func(void)
{
struct example_struct *flex_struct;
size_t i;
size_t array_size = 4;
/* Dynamically allocate memory for the struct */
flex_struct = (struct example_struct *)
malloc(sizeof(struct example_struct) + sizeof(int) * array_size);
if (flex_struct == NULL)
{
/* Handle error */
}
/* Initialize structure */
flex_struct->num = array_size;
for (i = 0; i < array_size; ++i)
{
flex_struct->data[i] = 0;
}
/* Handle structure */
/* Argument passed by value. 'data' not
copied to passed value. */
arg_by_value(*flex_struct);
/* Free dynamically allocated memory */
free(flex_struct);
}
В этом примере flex_struct
передается значением в качестве аргумента к arg_by_value
. В результате членские данные о массиве с переменными границами не копируются в передаваемый аргумент.
Исправление — структура передачи указателем на функцию
Чтобы гарантировать, что все члены структуры копируются в передаваемый аргумент, передайте flex_struct
arg_by_pointer
указателем.
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
struct example_struct
{
size_t num;
int data[];
};
extern void arg_by_pointer(struct example_struct *s);
void func(void)
{
struct example_struct *flex_struct;
size_t i;
size_t array_size = 4;
/* Dynamically allocate memory for the struct */
flex_struct = (struct example_struct *)
malloc(sizeof(struct example_struct) + sizeof(int) * array_size);
if (flex_struct == NULL)
{
/* Handler error */
}
/* Initialize structure */
flex_struct->num = array_size;
for (i = 0; i < array_size; ++i)
{
flex_struct->data[i] = 0;
}
/* Handle structure */
/* Structure passed by pointer */
arg_by_pointer(flex_struct);
/* Free dynamically allocated memory */
free(flex_struct);
}