CERT C: Rec. MEM02-C

Немедленно приведите результат вызова функции выделения памяти в указатель на выделенный тип

Описание

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

Немедленно приведите результат вызова функции выделения памяти в указатель на выделенный тип.[1]

Реализация Polyspace

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

Примеры

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

Проблема

Неправильный размер выделенного объекта для приведения происходит во время преобразования указателя, когда адрес указателя несовпадает. Если указатель преобразуется в другой тип указателя, размер выделенной памяти должен быть кратен размеру целевого указателя.

Риск

Удаление несовпадающего указателя имеет неопределенное поведение и может привести к сбою вашей программы.

Зафиксировать

Предположим, вы преобразуете указатель мыши ptr1 на ptr2. Если ptr1 указывает на буфер N байты и ptr2 является type * указатель, где sizeof (type) является n bytes, убедитесь, что N является целым числом, кратным n.

См. примеры исправлений ниже.

Если вы не хотите устранять проблему, добавьте комментарии к своему результату или коду, чтобы избежать другой проверки. Смотрите Адрес Результаты Polyspace через исправления ошибок или обоснования.

Пример - Динамическое распределение указателей
#include <stdlib.h>

void dyn_non_align(void){
    void *ptr = malloc(13);
    long *dest;

    dest = (long*)ptr; //defect
}

В этом примере программное обеспечение повышает дефект преобразования ptr в long*. Динамически выделяемая память ptr, 13 байт, не является произведением размера dest, 4 байта. Это несоответствие вызывает Неправильный размер выделенного объекта для дефекта приведения.

Коррекция - изменение размера указателя

Одной из возможных коррекций является использование размера указателя, кратного размеру получателя. В этом примере устраните дефект, изменив выделенную память на 12 вместо 13.

#include <stdlib.h>

void dyn_non_align(void){
    void *ptr = malloc(12);
    long *dest;

    dest = (long*)ptr;
}
Пример - Статическое распределение указателей
void static_non_align(void){
    char arr[13], *ptr;
    int *dest;

    ptr = &arr[0];
    dest = (int*)ptr; //defect
}

В этом примере программное обеспечение повышает дефект преобразования ptr в int* в линии 6. ptr имеет размер памяти 13 байт, поскольку массив arr имеет размер 13 байт. Размер dest 4 байта, что не кратно 13. Это несоответствие вызывает Неправильный размер выделенного объекта для дефекта приведения.

Коррекция - изменение размера указателя

Одной из возможных коррекций является использование размера указателя, кратного размеру получателя. В этом примере устраните дефект, изменив размер массива arr для кратного 4.

void static_non_align(void){
    char arr[12], *ptr;
    int *dest;

    ptr = &arr[0];
    dest = (int*)ptr;
}
Пример - Распределение функцией
#include <stdlib.h>

void *my_alloc(int size) { 
    void *ptr_func = malloc(size); 
    if(ptr_func == NULL) exit(-1); 
    return ptr_func; 
}

void fun_non_align(void){
    int *dest1;
    char *dest2;

    dest1 = (int*)my_alloc(13);  //defect
    dest2 = (char*)my_alloc(13); //not a defect
}

В этом примере программное обеспечение поднимает дефект преобразования указателя мыши, возвращенного my_alloc(13) в int* в линии 11. my_alloc(13) возвращает указатель с динамически выделенным размером 13 байт. Размер dest1 4 байта, что не является делителем 13. Это несоответствие вызывает Неправильный размер выделенного объекта для дефекта приведения. В линии 12 тот же вызов функции, my_alloc(13), не вызывает дефект для преобразования в dest2 потому что размер char*, 1 байт, делитель 13.

Коррекция - изменение размера указателя

Одной из возможных коррекций является использование размера указателя, кратного размеру получателя. В этом примере устраните дефект, изменив аргумент для my_alloc для кратного 4.

#include <stdlib.h>

void *my_alloc(int size) { 
    void *ptr_func = malloc(size); 
    if(ptr_func == NULL) exit(-1); 
    return ptr_func; 
}

void fun_non_align(void){
    int *dest1;
    char *dest2;

    dest1 = (int*)my_alloc(12); 
    dest2 = (char*)my_alloc(13); 
}

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

Группа: Рек. 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 Университет Карнеги Меллон, с специального разрешения от его Института программной инженерии.

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

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