Upozornění C26407
Upřednostňujte objekty s vymezeným oborem, nevydělujte zbytečně haldu (r.5).
Abychom se vyhnuli zbytečnému použití ukazatelů, snažíme se detekovat běžné vzory místních přidělení. Zjistíme například, kdy je výsledek volání operátoru new
uložen v místní proměnné a později explicitně odstraněn. Tato kontrola podporuje pravidlo C++ Core Guidelines R.5: Preferujte objekty s vymezeným oborem, nevydělujte zbytečně haldu. Pokud chcete tento problém vyřešit, použijte místo nezpracovaného ukazatele typ RAII a povolte práci s prostředky. Samozřejmě není nutné vytvořit typ obálky pro přidělení jednoho objektu. Místo toho by místní proměnná typu objektu fungovala lépe.
Poznámky
Aby se snížil počet upozornění, analýza kódu tento vzor rozpozná pouze u ukazatelů vlastníka. Proto je nejprve nutné označit vlastníky správně. Tuto analýzu můžeme snadno rozšířit tak, aby zahrnovala nezpracované ukazatele, pokud obdržíme zpětnou vazbu na komunitu vývojářů sady Visual Studio C++ od zákazníků, kteří tyto scénáře podporují.
Termín objektu s vymezeným oborem může být trochu zavádějící. Obecně doporučujeme použít buď místní proměnnou, jejíž životnost je automaticky spravována, nebo inteligentní objekt, který efektivně spravuje dynamické prostředky. Inteligentní objekty můžou provádět přidělení haldy, ale nejsou explicitní v kódu.
Pokud se upozornění aktivuje při přidělování polí, které je často potřeba pro dynamické vyrovnávací paměti, můžete ho opravit pomocí standardních kontejnerů nebo
std::unique_pointer<T[]>
.Vzor se detekuje pouze pro místní proměnné. V případech, kdy je přidělení přiřazené, například globální proměnnou, a poté odstraněno ve stejné funkci, neupozorníme.
Název analýzy kódu: DONT_HEAP_ALLOCATE_UNNECESSARILY
Příklad 1: Nepotřebné přidělení objektů v haldě
auto tracer = new Tracer();
ScanObjects(tracer);
delete tracer; // C26407
Příklad 2: Nepotřebné přidělení objektů u haldy (opraveno s místním objektem)
Tracer tracer; // OK
ScanObjects(&tracer);
Příklad 3: Nepotřebné přidělení vyrovnávací paměti u haldy
auto value = new char[maxValueSize];
if (ReadSetting(name, value, maxValueSize))
CheckValue(value);
delete[] value; // C26407
Příklad 4: Nepotřebné přidělení vyrovnávací paměti v haldě (opraveno s kontejnerem)
auto value = std::vector<char>(maxValueSize); // OK
if (ReadSetting(name, value.data(), maxValueSize))
CheckValue(value.data());