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++
По умолчанию: On для рукописного кода, off для сгенерированного кода
Синтаксис командной строки : FLEXIBLE_ARRAY_MEMBER_STRUCT_MISUSE
Влияние: Низкое
Введенный в R2017b