Unsafe conversion between pointer and integer

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

Описание

Этот дефект возникает при преобразовании между типами указателей, такими как intptr_t, или uintprt_t, и целого типа, такого как enum, ptrdiff_t, или pid_t, или наоборот.

Риск

Отображение между указателями и целыми числами не всегда согласуется со структурой адресации окружения.

Преобразование из указателей в целые числа может создать:

  • Усеченные или выходящие за пределы области значений целочисленные значения.

  • Недопустимые целые типы.

Преобразование из целых чисел в указатели может создать:

  • Несогласованные указатели или несогласованные объекты.

  • Недопустимые адреса указателей.

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

По возможности избегайте преобразования указателя на целое число или целого числа на указатель. Если вы хотите преобразовать void указатель на целое число, чтобы вы не изменили значение, используйте типы:

  • C99 — intptr_t или uintptr_t

  • C90 — size_t или ssize_t

Примеры

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

unsigned int *badintptrcast(void)
{
    unsigned int *ptr0 = (unsigned int *)0xdeadbeef;
    char *ptr1 = (char *)0xdeadbeef;
    return (unsigned int *)(ptr0 - (unsigned int *)ptr1);
}

В этом примере существует три преобразования, два небезопасных преобразования и одно безопасное преобразование. Первое преобразование 0xdeadbeef на unsigned int* вызывает проблемы выравнивания для указателя мыши. Второе преобразование 0xdeadbeef на char * безопасно, потому что нет проблем выравнивания для char. Третье преобразование в возврат приводит ptrdiff_t на указатель. Этот указатель может указывать или не указывать на недопустимый адрес.

Коррекция - Использование intptr_t

Одной из возможных коррекций является использование intptr_t типы для хранения адреса указателя 0xdeadbeef. Также можно изменить второй указатель на целое число смещения чтобы больше не было преобразования из ptrdiff_t на указатель.

#include <stdint.h>

unsigned int *badintptrcast(void)
{
    intptr_t iptr0 = (intptr_t)0xdeadbeef;
    int offset = 0;
    return (unsigned int *)(iptr0 - offset);
}

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

Группа: Программирование
Язык: C | C++
По умолчанию: Off
Синтаксис командной строки: BAD_INT_PTR_CAST
Влияние: Средний
ИДЕНТИФИКАТОР CWE: 465, 466, 587, 758
Введенный в R2016b