Aviso C26407
Prefira objetos com escopo, não aloce desnecessariamente (r.5)
Para evitar o uso desnecessário de ponteiros, tentamos detectar padrões comuns de alocações locais. Por exemplo, detectamos quando o resultado de uma chamada ao operador new
é armazenado em uma variável local e posteriormente excluído de maneira explícita. Essa verificação oferece suporte à regra R.5 das Diretrizes Principais do C++: Prefira objetos com escopo, não aloce desnecessariamente. Para corrigir o problema, use um tipo RAII em vez de um ponteiro bruto e permita que ele lide com recursos. Obviamente, não é necessário criar um tipo de wrapper para alocar um único objeto. No entanto, uma variável local do tipo do objeto funcionaria melhor.
Comentários
Para reduzir o número de avisos, a análise de código detecta apenas esse padrão em ponteiros de proprietário. Portanto, é necessário marcar primeiro os proprietários corretamente. Podemos estender facilmente essa análise para cobrir ponteiros brutos se recebermos comentários sobre a Comunidade de Desenvolvedores do Visual Studio C++ de clientes com suporte a esses cenários.
O termo objeto com escopo pode ser um pouco enganoso. Em geral, sugerimos que você use uma variável local cujo tempo de vida seja gerenciado automaticamente, ou um objeto inteligente que gerencie recursos dinâmicos com eficiência. Objetos inteligentes podem fazer alocações de heap, mas não está explícito no código.
Se o aviso for acionado na alocação de matriz, que geralmente é necessária para buffers dinâmicos, você poderá corrigi-lo usando contêineres padrão ou
std::unique_pointer<T[]>
.O padrão é detectado apenas em variáveis locais. Não avisamos nos casos em que uma alocação é atribuída a, digamos, uma variável global e, em seguida, excluída na mesma função.
Nome da análise de código: DONT_HEAP_ALLOCATE_UNNECESSARILY
Exemplo 1: alocação de objeto desnecessária no heap
auto tracer = new Tracer();
ScanObjects(tracer);
delete tracer; // C26407
Exemplo 2: alocação de objeto desnecessária no heap (corrigida com objeto local)
Tracer tracer; // OK
ScanObjects(&tracer);
Exemplo 3: alocação de buffer desnecessária no heap
auto value = new char[maxValueSize];
if (ReadSetting(name, value, maxValueSize))
CheckValue(value);
delete[] value; // C26407
Exemplo 4: alocação de buffer desnecessária no heap (corrigida com contêiner)
auto value = std::vector<char>(maxValueSize); // OK
if (ReadSetting(name, value.data(), maxValueSize))
CheckValue(value.data());