exponenta event banner

Неправильное использование структуры с гибким элементом массива

Выделение памяти игнорирует гибкий элемент массива

Описание

Этот дефект возникает в следующих случаях:

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

  • Назначение между структурами с гибким элементом массива выполняется без использования 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