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
Удар: носитель
ID CWE: 465, 466, 587, 758
Введенный в R2017b