﻿# Урок 14\. Паттерн 6\. Изменение типа массива

Иногда в программах необходимо \(или просто удобно\) представлять элементы массива в виде элементов другого типа\. Опасное и безопасное приведение типов представлено в следующем коде:

```cpp
int array[4] = { 1, 2, 3, 4 };
enum ENumbers { ZERO, ONE, TWO, THREE, FOUR };
//safe cast (for MSVC)
ENumbers *enumPtr = (ENumbers *)(array);
cout << enumPtr[1] << " ";
//unsafe cast
size_t *sizetPtr = (size_t *)(array);
cout << sizetPtr[1] << endl;
//Output on 32-bit system: 2 2
//Output on 64-bit system: 2 17179869187
```

Как видите, результат вывода программы отличается в 32\-битном и 64\-битном варианте\. На 32\-битной системе доступ к элементам массива осуществляется корректно, так как размеры типов [size\_t](https://pvs-studio.ru/ru/blog/terms/0044/) и int совпадают, и мы видим вывод "2 2"\.

На 64\-битной системе мы получили в выводе "2 17179869187", так как именно значение 17179869187 находится в 1\-ом элементе массива sizetPtr \(см\. рисунок 1\)\. В некоторых случаях именно такое поведение и бывает нужно, но обычно это является ошибкой\.

_Примечание\. Тип enum в компиляторе Visual C\+\+ по умолчанию совпадает размером с типом int, то есть является 32\-битным типом\. Использование enum другого размера возможно только с помощью расширения, считающимся нестандартным Visual C\+\+\. Поэтому приведенный пример корректен в Visual C\+\+, но с точки зрения других компиляторов приведение указателя на элементы int к указателю на элементы enum может быть также некорректным\._

![14_Pattern_06_Changing_an_arrays_type_ru/image1.png](https://import.viva64.com/docx/blog/14_Pattern_06_Changing_an_arrays_type_ru/image1.png)

_Рисунок 1 \- Расположение элементов массивов в памяти_

Исправление описанной ситуации заключается в отказе от опасных приведений типов путем модернизации программы\. Другим вариантом является создание нового массива и копирование в него значений из исходного массива\.

В основном описанный паттерн ошибки встречается в коде, где в качестве уникальных 32\-битных идентификаторов пытаются использовать значения указателей\.

## Диагностика

Опасные изменения типа массива диагностируются инструментом [PVS\-Studio](https://pvs-studio.ru/ru/pvs-studio/)\. Анализатор предупреждает о потенциально опасных приведениях типа с помощью диагностических сообщений [V114](https://pvs-studio.ru/ru/docs/warnings/v114/)\. Соответственно, выводятся предупреждения только о тех конструкциях, которые могут привести к ошибке на 64\-битной системе\. Например, следующий код является корректным и анализатор не обратит на него внимание программиста:

```cpp
void **pointersArray;
ptrdiff_t correctID = ((ptrdiff_t *)pointersArray)[index];
```

_Авторы курса: Андрей Карпов \([karpov@viva64\.com](mailto:karpov@viva64.com)\), Евгений Рыжков \([evg@viva64\.com](mailto:evg@viva64.com)\)\._

_Правообладателем курса "Уроки разработки 64\-битных приложений на языке Си/Си\+\+" является ООО "Системы программной верификации"\. Компания занимается разработкой программного обеспечения в области анализа исходного кода программ\. [Сайт компании](https://pvs-studio.ru/ru/pvs-studio/)\._