Aracılığıyla paylaş


crt kitaplığını kullanarak bellek sızıntıları bulma

Doğru önceden ayrılmış olan belleği ayırması hatası olarak tanımlanan bellek sızıntıları c/C++ uygulamalarında en ince ve algılayan sabit hatalar arasında aşağıdakiler vardır. Küçük bellek sızıntısı en önce ancak zaman içinde fark değil, aşamalı bellek sızıntısı belirtileri aralığı performansla bellek yetersiz uygulama çalışırken kilitlenen için neden olabilir. Worse, tüm kullanılabilir belleği kullanan leaking uygulama kilitlenme başka bir uygulamanın uygulama sorumlu olduğu için karışıklık oluşturmak neden olabilir. Olsa da görünüşte zararsız bellek sızıntıları symptomatic düzeltilmesi diğer sorunlar olabilir.

Visual Studio c çalışma zamanı (crt) kitaplıklarını ve hata ayıklayıcı sağlar algılama ve bellek sızıntılarını belirlemek anlamına gelir.

Bellek sızıntısı algılama etkinleştirme

Bellek sızıntılarını hata ayıklayıcı ve c çalışma zamanı kitaplıkları (crt) olan algılamak için birincil araçlar öbek işlevleri hata ayıklama.

Hata ayıklama öbek işlevlerini etkinleştirmek için aşağıdaki ifadeleri programınıza ekleyin:

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

crt işlevlerinin düzgün çalışması #include ifadeleri burada gösterilen sırayla izleyin gerekir.

Crtdbg.h haritalar dahil malloc ve ücretsiz işlevleri hata ayıklama sürümleri için _malloc_dbg ve free, bellek ayırma ve kaldırma izlemek. Olan yalnızca hata ayıklama yapılarında, bu eşleştirme ortaya _DEBUG. Yayın yapılar kullanan normal malloc ve free fonksiyonlar.

#define Deyimi crt öbek işlevlerini temel bir sürümünü karşılık gelen hata ayıklama sürümü için eşleştirir. Atlarsanız #define deyimi, bellek sızıntısı dökümü daha az ayrıntılı.

Bu ifadeler kullanarak hata ayıklama öbek işlevleri etkinleştirdikten sonra bir çağrı yerleştirmek _CrtDumpMemoryLeaks önce uygulamanız çıktığında bir bellek sızıntısı raporu görüntülemek için uygulama çıkış noktası:

_CrtDumpMemoryLeaks();

Uygulamanızı birden fazla çıkar varsa, el ile yapılan bir çağrı yerleştirmek gerek yoktur _CrtDumpMemoryLeaks her çıkış noktası. Çağrı _CrtSetDbgFlag otomatik bir çağrı uygulama başında neden olur _CrtDumpMemoryLeaks her biri çıkış noktası. Burada gösterilen iki bit alanları ayarlamanız gerekir:

_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

Varsayılan olarak, _CrtDumpMemoryLeaks bellek sızıntısı rapor verir Debug bölmesinde Çıkış pencere. Kullanabileceğiniz _CrtSetReportMode raporu başka bir konuma yeniden yönlendirmek için.

Kitaplığı kullanıyorsanız, kitaplık, başka bir yere çıktı sıfırlayabilir. Bu durumda çıkış konumunu ayarlamak geri Çıkış penceresinde, aşağıda gösterildiği gibi:

_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );

Bellek sızıntısı rapor yorumlama

Uygulamanızın değil tanımlarsanız, _CRTDBG_MAP_ALLOC, _CrtDumpMemoryLeaks aşağıdakine benzer şekilde bir bellek sızıntısı raporda görüntülenir:

Detected memory leaks!
Dumping objects ->
{18} normal block at 0x00780E80, 64 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.

Uygulamanızın tanımlıyorsa _CRTDBG_MAP_ALLOC, bellek sızıntısı raporu şöyle görünür:

Detected memory leaks!
Dumping objects ->
C:\PROGRAM FILES\VISUAL STUDIO\MyProjects\leaktest\leaktest.cpp(20) : {18} 
normal block at 0x00780E80, 64 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.

Farktır sızdırılan bellek ilk ayrılan yere ikinci rapor dosyasının adını ve satır numarasını gösterir.

Tanımladığınız olup _CRTDBG_MAP_ALLOC ya da değil, bellek sızıntısı rapor olacak aşağıdaki bilgileri görüntüler:

  • Bellek ayırma numarası 18 Bu örnekte

  • Blok türü, hangi normal Bu örnekte.

  • Olan onaltılı bellek konumuna 0x00780E80 Bu örnekte.

  • Blok boyutu 64 bytes Bu örnekte.

  • Verileri onaltılık biçimde bloktaki ilk 16 bayt.

Bellek sızıntısı rapor normal, istemci ya da crt bellek bloğunu tanımlar. A normal blok sıradan bellek programınız tarafından ayrılmış. A İstemci blok bir yıkıcı gerektiren nesneler için mfc programlar tarafından kullanılan bellek bloğu özel bir türüdür. mfc new operator normal blok veya oluşturulan nesne için uygun bir istemci bloğu oluşturur. A crt blok crt kitaplığı kendi kullanımı için ayrılmış. crt kitaplığı kaldırma bu blokları için işler. Bu nedenle, göreceksiniz bu bellek sızıntısı raporunda önemli ölçüde olmadığı sürece yanlış, örneğin, crt kitaplığı bozuk düşüktür.

Hiçbir bellek sızıntısı raporlarında görünür bellek bloklarının iki türü vardır. A boş blok serbest bırakıldı bellektir. Bu, tanım olarak sızdırılır değil anlamına gelir. Bir Blok yoksay bellek sızıntısı raporun dışında bırakma açıkça işaretlenmiş bellek.

Bu teknikler kullanılarak standart crt ayrılmış bellek için çalışma malloc işlevi. Programınız C++ kullanarak bellek ayırırsa new işleci, ancak yeniden tanımlamak için gereksinim duyduğunuz new bellek sızıntısı rapor dosyası ve satır numaralarını görmek isterseniz. Şöyle bir kod bloğu ile yapabilirsiniz:

#ifdef _DEBUG   #ifndef DBG_NEW      #define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )      #define new DBG_NEW   #endif#endif  // _DEBUG

Kesme noktası bir bellek ayırma numarasını ayarlama

Bellek ayırma sayısı ne zaman sızdırılan bellek bloğu tahsis söyler. Blok ile bellek ayırma sayısı 18, örneğin, 18th uygulama çalışması sırasında ayrılmış olan belleği taşıdır. crt rapor çalıştırma sırasında tüm bellek bloğu ayırmaları sayar. Bu, ayırma crt kitaplığı ve mfc gibi diğer kitaplıkları içerir. Bu nedenle, bir bellek ayırma sayısı 18 blok kodunuz tarafından ayrılan 18th bellek bloğu olmayabilir. Genellikle, bu olur.

Bellek ayırma bir kesme noktası ayarlamak için ayırma numarasını kullanabilirsiniz.

Gözcü penceresini kullanarak bir bellek ayırma kesme noktası ayarlamak için

  1. Uygulama Başlat bir kesme noktası ayarlamak ve uygulamanızın başlatın.

  2. Uygulama kesme noktasında böldüğünde İzle pencere.

  3. İçinde İzle pencere, türü _crtBreakAlloc de, adı sütun.

    crt kitaplığı (/md seçeneği) çok iş parçacıklı dll sürümünü kullanıyorsanız, içerik işleci içerir:{,,msvcr100d.dll}_crtBreakAlloc

  4. Press DÖNMEK.

    Hata ayıklayıcı arama değerlendirir ve sonucu yerleştirir değeri sütun. Bellek ayırmalarını tüm kırılma noktalarını ayarlamadıysanız, bu değer –1 olacaktır.

  5. İçinde değeri sütunu, bellek ayırma ayırma sayısı kesmek istediğiniz yeri gösterilen değerini değiştirin.

Kesme noktası bir bellek ayırma numarasını belirledikten sonra hata ayıklama devam edebilirsiniz. Bellek ayırma sırası değişmez önceki çalışma programı aynı koşullar altında çalışmaya özen gösterin. Program sırasında belirtilen bellek ayırma böldüğünde kullanabilirsiniz Call Stack pencere ve diğer hata ayıklayıcı windows altında bellek tahsis koşulları belirleyin. Sonra nesneye neler gözlemek için yürütme devam ve neden onu değil doğru ayırmanın belirlenir.

Nesnede veri kesme ayarını da yardımcı olabilir. Daha fazla bilgi için bkz. Nasıl yapılır: (yalnızca yerel) veri kesme noktası ayarlamak.

Ayrıca, bellek ayırma kesme kodu ayarlayabilirsiniz. Bunun için iki yol vardır:

_crtBreakAlloc = 18;

ya da:

_CrtSetBreakAlloc(18);

Bellek durumlarını karşılaştırma

Önemli noktalarda uygulamanın bellek durumunu anlık görüntü alınması bellek sızıntıları bulmak için başka bir yöntem içerir. Anlık bellek durumu belirli bir noktada uygulamanıza almak oluşturmak bir _CrtMemState yapı ve ona _CrtMemCheckpoint işlevi. Bu işlev geçerli bellek durumunu anlık yapısıyla doldurur:

_CrtMemState s1;
_CrtMemCheckpoint( &s1 );

_CrtMemCheckpointGeçerli bellek durumunu anlık yapısıyla doldurur.

İçeriğinin çıktı için bir _CrtMemState yapı, yapı geçmesi _ CrtMemDumpStatistics işlevi:

_CrtMemDumpStatistics( &s1 );

_ CrtMemDumpStatisticsbellek durumunu şöyle bir dökümünü verir:

0 bytes in 0 Free Blocks.
0 bytes in 0 Normal Blocks.
3071 bytes in 16 CRT Blocks.
0 bytes in 0 Ignore Blocks.
0 bytes in 0 Client Blocks.
Largest number used: 3071 bytes.
Total allocations: 3764 bytes.

Bellek sızıntısı kod bölümünde oluşup oluşmadığını belirlemek için önce ve sonra bölüm bellek durumunun anlık görüntüsünü ve sonra gerçekleştirebilirsiniz _ CrtMemDifference iki durumu karşılaştırmak için:

_CrtMemCheckpoint( &s1 );
// memory allocations take place here
_CrtMemCheckpoint( &s2 );

if ( _CrtMemDifference( &s3, &s1, &s2) )
   _CrtMemDumpStatistics( &s3 );

_CrtMemDifferencebellek durumlarını karşılaştıran s1 ve s2 ve sonuç olarak döner (s3), yani fark s1 ve s2.

Bellek sızıntıları bulma bir tekniği koyarak başlar _CrtMemCheckpoint çağrıları başında ve sonunda sonra uygulamanızın _CrtMemDifference sonuçları karşılaştırmak için. _CrtMemDifference Daha fazla ekleyebilirsiniz bir bellek sızıntısı gösterir _CrtMemCheckpoint sızıntı kaynağı buluncaya kadar ikili arama kullanarak program bölmek için çağrı.

Yanlış pozitif durumlar

Bazı durumlarda, _CrtDumpMemoryLeaks bellek sızıntıları yanlış göstergeleri verebilirsiniz. İç ayırma yerine _NORMAL_BLOCKs olarak işaretler kitaplığı kullanıyorsanız, bu durum oluşabilir _CRT_BLOCKs veya _CLIENT_BLOCKs. Bu durumda, _CrtDumpMemoryLeaks kullanıcı ayırma ve iç kitaplığı ayırmaları arasındaki fark edemiyor. Genel kitaplığı ayırmaları için burada arama noktasından sonra yýkýcýlarý, _CrtDumpMemoryLeaks, her iç kitaplığı ayırma, bellek sızıntısı bildirdi. Eski standart Şablon Kütüphanesi, Visual Studio'nun önceki sürümleri.net, neden _CrtDumpMemoryLeaks gibi yanlış bildirmek için pozitif ama bu sabit son sürümlerde.

Ayrıca bkz.

Kavramlar

Hata ayıklayıcı güvenlik

Diğer Kaynaklar

crt Debug öbek

Yerel kod hata ayıklama

mfc bellek sızıntısı algılama