Avertissement C26407
Préférer les objets délimités, ne pas allouer inutilement (r.5)
Pour éviter l’utilisation inutile de pointeurs, nous essayons de détecter les modèles courants d’allocations locales. Par exemple, nous détectons quand le résultat d’un appel à un opérateur new
est stocké dans une variable locale et supprimé explicitement. Cette vérification prend en charge la règle C++ Core Guidelines R.5 : Préférer les objets délimités, ne pas allouer inutilement de tas. Pour résoudre le problème, utilisez un type RAII au lieu d’un pointeur brut et autorisez-le à gérer les ressources. Évidemment, il n’est pas nécessaire de créer un type wrapper pour allouer un seul objet. Au lieu de cela, une variable locale du type de l’objet fonctionne mieux.
Notes
Pour réduire le nombre d’avertissements, l’analyse du code détecte uniquement ce modèle pour les pointeurs propriétaires. Il est donc nécessaire de marquer les propriétaires correctement. Nous pouvons facilement étendre cette analyse pour couvrir les pointeurs bruts si nous recevons des commentaires sur visual Studio C++ Developer Community des clients dans le support de ces scénarios.
Le terme objet délimité peut être un peu trompeur. En général, nous vous suggérons d’utiliser une variable locale dont la durée de vie est gérée automatiquement ou un objet intelligent qui gère efficacement les ressources dynamiques. Les objets intelligents peuvent effectuer des allocations de tas, mais ce n’est pas explicite dans le code.
Si l’avertissement se déclenche sur l’allocation de tableau, qui est souvent nécessaire pour les mémoires tampons dynamiques, vous pouvez le corriger à l’aide de conteneurs standard ou
std::unique_pointer<T[]>
.Le modèle est détecté uniquement pour les variables locales. Nous n’avertissons pas dans les cas où une allocation est affectée, par exemple, à une variable globale, puis supprimée dans la même fonction.
Nom de l’analyse du code : DONT_HEAP_ALLOCATE_UNNECESSARILY
Exemple 1 : Allocation d’objets inutiles sur le tas
auto tracer = new Tracer();
ScanObjects(tracer);
delete tracer; // C26407
Exemple 2 : Allocation d’objets inutiles sur le tas (fixe avec un objet local)
Tracer tracer; // OK
ScanObjects(&tracer);
Exemple 3 : Allocation de mémoires tampons inutiles sur le tas
auto value = new char[maxValueSize];
if (ReadSetting(name, value, maxValueSize))
CheckValue(value);
delete[] value; // C26407
Exemple 4 : Allocation de mémoire tampon inutile sur le tas (fixe avec un conteneur)
auto value = std::vector<char>(maxValueSize); // OK
if (ReadSetting(name, value.data(), maxValueSize))
CheckValue(value.data());