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

Выделенная память не соответствует указателю назначения

Описание

Этот дефект возникает во время преобразования указателя, когда адрес указателя не выровнен. Если указатель преобразуется в другой тип указателя, размер выделенной памяти должен быть кратен размеру указателя назначения.

Риск

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

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

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

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

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

Примеры

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

#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); 
}

Информация о результатах

Группа: Статическая память
Язык: C | C++
По умолчанию: Откл.
Синтаксис командной строки: OBJECT_SIZE_MISMATCH
Воздействие: Высокое
CWE ID: 704
Представлен в R2013b