Aracılığıyla paylaş


Uyarı C26407

Kapsamlı nesneleri tercih edin, gereksiz yere yığın ayırmayın (r.5)

İşaretçilerin gereksiz kullanımını önlemek için, yerel ayırmaların yaygın desenlerini algılamaya çalışırız. Örneğin, bir çağrı işlecinin new sonucunun yerel bir değişkende depolandığını ve daha sonra açıkça silindiğini algılarız. Bu denetim, C++ Çekirdek Yönergeleri kuralını destekler R.5: Kapsamlı nesneleri tercih edin, gereksiz yere yığın ayırmayın. Sorunu düzeltmek için ham işaretçi yerine BIR RAII türü kullanın ve kaynaklarla ilgilenmesine izin verin. Açıkçası, tek bir nesne ayırmak için sarmalayıcı türü oluşturmak gerekli değildir. Bunun yerine, nesne türünün yerel değişkeni daha iyi çalışır.

Açıklamalar

  • Uyarı sayısını azaltmak için kod analizi yalnızca sahip işaretçileri için bu düzeni algılar. Bu nedenle, önce sahipleri düzgün bir şekilde işaretlemek gerekir. Bu tür senaryoları destekleyen müşterilerden Visual Studio C++ Geliştirici Topluluğu hakkında geri bildirim alırsak, bu analizi kolayca ham işaretçileri kapsayacak şekilde genişletebiliriz.

  • Kapsamı belirlenmiş nesne terimi biraz yanıltıcı olabilir. Genel olarak, yaşam süresi otomatik olarak yönetilen yerel bir değişken veya dinamik kaynakları verimli bir şekilde yöneten akıllı bir nesne kullanmanızı öneririz. Akıllı nesneler yığın ayırmaları yapabilir, ancak kodda açık değildir.

  • Uyarı, genellikle dinamik arabellekler için gerekli olan dizi ayırmada tetiklenirse, standart kapsayıcıları veya std::unique_pointer<T[]>kullanarak bunu düzeltebilirsiniz.

  • Desen yalnızca yerel değişkenler için algılanır. Bir ayırmanın genel değişkene atandığı ve ardından aynı işlevde silindiği durumlarda uyarmayız.

Kod analizi adı: DONT_HEAP_ALLOCATE_UNNECESSARILY

Örnek 1: Yığında gereksiz nesne ayırma

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

Örnek 2: Yığında gereksiz nesne ayırma (yerel nesneyle düzeltildi)

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

Örnek 3: Yığında gereksiz arabellek ayırma

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

Örnek 4: Yığında gereksiz arabellek ayırma (kapsayıcı ile düzeltildi)

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