Sdílet prostřednictvím


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());