Поделиться через


Предупреждение C26407

Предпочитайте область d-объекты, не выделяете кучи ненужно (r.5)

Чтобы избежать ненужного использования указателей, мы пытаемся обнаружить распространенные шаблоны локальных выделений. Например, мы обнаруживаем, когда результат вызова оператора new хранится в локальной переменной и позже явно удален. Эта проверка поддерживает правило основных рекомендаций C++R.5. Предпочитайте область объекты, не распределяйте кучу без необходимости. Чтобы устранить проблему, используйте тип RAII вместо необработанного указателя и разрешите ему работать с ресурсами. Очевидно, что для выделения одного объекта не требуется создать тип оболочки. Вместо этого локальная переменная типа объекта будет работать лучше.

Замечания

  • Чтобы уменьшить количество предупреждений, анализ кода обнаруживает только этот шаблон для указателей владельца. Таким образом, сначала необходимо пометить владельцев должным образом. Этот анализ можно легко расширить, чтобы покрыть необработанные указатели, если мы получаем отзывы о Сообщество разработчиков Visual Studio C++ от клиентов в поддержке таких сценариев.

  • Термин область объекта может быть немного вводящим в заблуждение. Как правило, мы рекомендуем использовать локальную переменную, время существования которой автоматически управляется, или интеллектуальный объект, который эффективно управляет динамическими ресурсами. Интеллектуальные объекты могут выполнять выделение кучи, но в коде это не явно.

  • Если предупреждение возникает при выделении массива, которое часто требуется для динамических буферов, его можно исправить с помощью стандартных контейнеров или std::unique_pointer<T[]>.

  • Шаблон обнаруживается только для локальных переменных. Мы не предупреждаем в случаях, когда выделение назначается глобальной переменной, а затем удаляется в той же функции.

Имя анализа кода: DONT_HEAP_ALLOCATE_UNNECESSARILY

Пример 1. Выделение ненужных объектов в куче

auto tracer = new Tracer();
ScanObjects(tracer);
delete tracer;  // C26407

Пример 2. Выделение ненужных объектов в куче (исправлено с локальным объектом)

Tracer tracer;  // OK
ScanObjects(&tracer);

Пример 3. Ненужное выделение буфера в куче

auto value = new char[maxValueSize];
if (ReadSetting(name, value, maxValueSize))
    CheckValue(value);
delete[] value; // C26407

Пример 4. Ненужное выделение буфера в куче (исправлено с контейнером)

auto value = std::vector<char>(maxValueSize); // OK
if (ReadSetting(name, value.data(), maxValueSize))
    CheckValue(value.data());