2016-04-02 12 views
0

Yeni [] kullanılarak ayrılmış bir işaretçi üzerinde silme kullanırsanız bir bellek sızıntısı olduğunu kanıtlayan basit bir uygulama yazmak istiyorum.Silinin, yeni [] ayırdığı tüm belleği ayırmadığını nasıl gösterebilirim?

Şu anda CRT Debug kitaplığını, uygulamadan sonra belleği ayırmak için bellek ayırdıktan sonra ve yanlış ayrıldıktan sonra bellekte izlemek için kullanıyorum. Burada benim test kodu bakınız:

#define _CRTDBG_MAP_ALLOC 
#include <stdlib.h> 
#include <crtdbg.h> 
#include <iostream> 
#include <memory> 

using namespace std; 

int main() 
{ 
    _CrtMemState s1, s2, mem_diff; 

    // Allocate 40 bytes of memory. 
    int *leak = new int[10]; 

    // Capture the memory state after the allocation. 
    _CrtMemCheckpoint(&s1); 

    // Deallocate that memory with incorrect delete operator.  
    delete leak; 

    // Capture and compare the memory after the deallocation. 
    _CrtMemCheckpoint(&s2); 
    _CrtMemDifference(&mem_diff, &s1, &s2); 
    _CrtMemDumpStatistics(&mem_diff); 

    return 0; 
} 

Ancak, benim hata ayıklama çıkışı Ben 40 byte ayırmanın görüyoruz.

0 bytes in 0 Free Blocks. 
-40 bytes in -1 Normal Blocks. 
0 bytes in 0 CRT Blocks. 
0 bytes in 0 Ignore Blocks. 
0 bytes in 0 Client Blocks. 
Largest number used: 0 bytes. 
Total allocations: 0 bytes. 

bu çalışma neden için Benim diğer fikir tanımsız davranış olduğunu ve bu durumda derleyici özgü davranış olmasıdır: Bu Visual Studio 2015 Express benim ayıklama konsolundan çıkıştır.

+1

Son cümle - Bu çok makul bir yorumdur;) –

+0

Neden bunun her şeyi tahsis etmeyeceğini düşünüyorsunuz? – Soren

+1

Önemsiz türlerde, 'int' gibi, VC++ 'nın' delete 've 'delete []' için tam olarak aynı kodu oluşturduğu bilinir. –

cevap

1
void leak_via_wrong_delete() { 
    std::vector<int>* buff = new std::vector<int>[1000]; 
    for (auto i = 0; i < 1000; ++i) 
    buff[i].resize(i * 1000); 
    delete buff; 
} 

Bunu, kaçak tespit kodunuzla sarın. Uygulamada, delete[]'un neden önemli olduğunun asıl nedeni, bildiğim çoğu uygulamada dizideki tüm öğelerin yıkıcısını çağırmasıdır. (Ayrıca felakete yol açmayan bir orta-karanlık platform olabilir, hatırlayamıyorum).

Önemsiz bir yok etme olmadan sınıflar için,numaralı bayttan önce atanan dizinin başlangıcınınumaralı bayttaki öğelerin sayısını (veya benzerlerini) saklarlar. Sonra delete[] inceler ve sırayla her bir nesneyi yok eder.

+0

Testimi, önerdiğiniz ilkel türler yerine bir dizi nesneyle tekrar denedim, CRT bunu hata ayıklama modunda algılıyor ve bir kesme noktasını tetikliyor, böylece bellek istatistiklerimi yazdırmaya devam edemedim. Ancak hafızayı inceledim ve anlattığınız gibi, dizi dizilimini saklayan dizimden hemen önce 4 bayt ayrıldı. Bu, ints içeren dizimden önce görünmedi. –

İlgili konular