Misuse of structure with flexible array member

Выделение памяти игнорирует член массива с переменными границами

Описание

Этот дефект происходит когда:

  • Вы задаете объект с членом массива с переменными границами неизвестного размера во время компиляции.

  • Вы делаете присвоение между структурами с членом массива с переменными границами, не используя 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);
} 

Информация о результате

Группа: Программирование
Язык: C | C++
Значение по умолчанию: На для рукописного кода, прочь для сгенерированного кода
Синтаксис командной строки: FLEXIBLE_ARRAY_MEMBER_STRUCT_MISUSE
Удар: низко
Введенный в R2017b