CERT C: правило MEM33-C

Выделите и скопируйте структуры, содержащие участника массива с переменными границами динамически

Описание

Управляйте определением

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

Примеры

развернуть все

Описание

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

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

  • Вы делаете присвоение между структурами с участником массива с переменными границами, не используя 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 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.

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

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