CERT C: Rule MEM33-C

Динамическое выделение и копирование структур, содержащих гибкий представитель массива

Описание

Определение правила

Динамическое выделение и копирование структур, содержащих гибкий представитель массива.[1]

Реализация Polyspace

Эта проверка проверяет неправильное использование структуры с гибким представителем массива.

Примеры

расширить все

Проблема

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

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

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

Проверяйте информацию

Группа: Правило 08. Управление памятью (MEM)
Введенный в R2019a

[1] Это программное обеспечение было создано MathWorks, включающее фрагменты: «Сайт SEI CERT-C», © 2017 Университет Карнеги Меллон, Веб-сайт SEI CERT-C + + © 2017 Университет Карнеги Меллон, "Стандарт кодирования SEI CERT C - Правила разработки безопасных, Надежные и безопасные системы - 2016 Edition ", © 2016 Университет Карнеги Меллон, и "Стандарт кодирования SEI CERT C++ - Правила разработки безопасных, Надежные и безопасные системы в C++ - 2016 Edition "© 2016 Университет Карнеги Меллон, с специального разрешения от его Института программной инженерии.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ МЕЛЛОН И/ИЛИ ЕГО ИНЖЕНЕРНОГО ИНСТИТУТА ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, СОДЕРЖАЩИЙСЯ В НАСТОЯЩЕМ ДОКУМЕНТЕ, ПОСТАВЛЯЕТСЯ НА БАЗИСЕ «КАК ЕСТЬ». УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ, ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, В ОТНОШЕНИИ ЛЮБОГО ВОПРОСА, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИЮ ПРИГОДНОСТИ ДЛЯ ЦЕЛЕЙ ИЛИ КОММЕРЧЕСКОЙ ВЫГОДЫ, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ В ОТНОШЕНИИ СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКИХ ПРАВ.

Это программное обеспечение и связанная с ним документация не были рассмотрены и не одобрены Университетом Карнеги-Меллон или его Институтом программной инженерии.