Когда я использую динамически выделяемый массив в C ++, я получаю C6386 предупреждение , выдаваемое анализом кода Visual Studio 2019.
Вот минимальный воспроизводимый пример:
#include <vector>
int main()
{
std::vector<int> someInts{ 1, 2, 3 };
int* dynamicInts = new int[someInts.size()];
for (size_t i = 0; i < someInts.size(); i++)
{
dynamicInts[i] = someInts[i];
}
delete[] dynamicInts;
}
Смысл в том, что у нас есть вектор целых чисел, и мы хотим по какой-то причине скопировать их в динамически выделяемый массив целых чисел. (Немного глупый пример, но он показывает проблему). Он использует size()
вектора во время выделения массива dynamicInts
и в качестве верхней границы l oop, поэтому не должно быть проблем с переполнением буфера, которые я вижу.
Но этот код генерирует:
main.cpp(11): warning C6386: Buffer overrun while writing to 'dynamicInts': the writable size is 'someInts.public: unsigned int __thiscall std::vector<int,class std::allocator<int> >::size(void)const ()*4' bytes, but '8' bytes might be written.
Подробное объяснение в Список ошибок объясняет это как:
7: 'dynamicInts' is an array of 1 elements (4 bytes)
9: Enter this loop. (assume 'i<someInts.size()')
9: 'i' may equal 1
9: Continue this loop. (assume 'i<someInts.size()')
11: 'i' is an In/Out argument to 'std::vector<int,std::allocator<int> >::[]'
11: Invalid to write to 'dynamicInts[1]'. (writable range is 0 to 0)
Эти сообщения предполагают, что анализатор считает, что массив dynamicsInts
- это всего лишь один элемент.
Это кажется странным. Я знаю «Анализ кода сложен», , но, конечно же, у анализатора есть вся информация, необходимая для определения длины массива и привязки l oop?
Так это просто ложноотрицательный результат анализа кода? Или мне что-то не хватает?
Если это ложноотрицательный результат, то как лучше всего избежать этого предупреждения, не добавляя подавление и не предполагая, что нам нужно придерживаться динамически выделяемых массивов?