Önceki başlık :: Sonraki başlık |
Yazar |
Mesaj |
sensei
Kayıt: Nov 22, 2002 Mesajlar: 80 Nereden: istanbul
|
Tarih: Wed Apr 28, 2004 5:59 pm Mesaj konusu: |
|
|
------------------- CUT HERE ------------------------------
#pragma once
#include
namespace realtime {
namespace debug {
namespace _internal {
inline void xdbg_dumper(void *ptr, void *) {
int block = _CrtReportBlockType(ptr);
_RPT3(_CRT_WARN, "dumper found block at %p: type %d, subtype %d\n", ptr, _BLOCK_TYPE(block), _BLOCK_SUBTYPE(block));
}
inline void xdbg_leak_dumper(void *ptr, size_t sz) {
int block = _CrtReportBlockType(ptr);
_RPT4(_CRT_WARN, "leak_dumper found block at %p: type %d, subtype %d, size %d\n", ptr,_BLOCK_TYPE(block), _BLOCK_SUBTYPE(block), sz
);
}
}
inline void xdbg_initialize(void) {
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
}
inline void xdbg_uninitialize(void) {
_CrtDoForAllClientObjects(_internal::xdbg_dumper, NULL);
_CrtSetDumpClient(_internal::xdbg_leak_dumper);
}
inline void xdbg_breakpoint(int allocNumber) {
_CrtSetBreakAlloc(allocNumber);
}
}
}
------------------------------- CUT END ----------------------------------
kullandigim bi leak finder kullanmayanlar varsa kullansin diye yaziim dedim.. .
void main() {
realtime::debug::xdbg_initialize();
// kod buraya.... diyelim...
int * a = new int;
realtime::debug::xdbg_uninitialize();
}
bunun sonucunda size dump yaparken KACH NUMARALI ALLOCATION'in FREE edilmedigini gosterir..
Detected memory leaks!
Dumping objects ->
{47} normal block at 0x00322F68, 4 bytes long.
Data: < > CD CD CD CD
Object dump complete.
gibi..eger console app calishtirirsaniz.. bunu console'a da yazar. .(CTRL + F5 ile calishtirsaniz bile)
yukaridaki ornek {47} no lu allocation free edilmemish diyor ornegin (tabi 1'den fazla olabilir bunnar)
ondan sonra yapilacak ish....
void main() {
realtime::debug::xdbg_initialize();
realtime::debug::xdbg_breakpoint(47); // 47.ci allocation yapildiginda break et...
// (TABI F5 ile calishtirin.. CTRL + F5 degil...)
// sonra STACK TRACE'den geri git ki anla nerde olmush..
realtime::debug::xdbg_uninitialize();
}
kodu kendinize gore adapte edebilirsiniz tabe. .namespace cart curt gereksiz gelebilir..
bi de COM geyiklerde azicik ichlere dallanabiliyo (ornegin DirectX objelerinde) yani stack trace'e biraz daha dikkatli bakila o tip durumlarda..
release mode'da hich iplemez bunnari.. telesha gerek yok yani....
|
|
Başa dön |
|
|
ferdemoncel
Kayıt: Nov 03, 2003 Mesajlar: 277 Nereden: Eskişehir
|
Tarih: Wed Apr 28, 2004 6:26 pm Mesaj konusu: |
|
|
Kodu denemedim ama tam olarak ne işlem yapıyor bu kod. Bellek sızıntılarını mı veriyor.
Ya da sen bu kodu ne için kullanıyorsun? |
|
Başa dön |
|
|
sensei
Kayıt: Nov 22, 2002 Mesajlar: 80 Nereden: istanbul
|
Tarih: Wed Apr 28, 2004 7:33 pm Mesaj konusu: |
|
|
evet aynen onu veriyor...
yani .. basit ornek.. .
void sivazla(int * p) {
p = 10;
}
void main() {
int * a = new int;
sivazla(a);
...
}
dedin ve delete a demeyi unuttun.. hashir sooluyo ishte.. direk olarak o NEW'in yapildigi satiri gosteriyo.. burada alloc etmishin ama free etmemishin diye...
yani ishe yariyabilir.. (benim bayaaaaa bi yariyo.. delete / free gibi sheyleri unutup unutmadigini sooluyo ozetle.. veya DX kulaniyosan. .RELEASE().. gibi sheyleri) |
|
Başa dön |
|
|
mentat
Kayıt: Oct 15, 2002 Mesajlar: 528
|
Tarih: Wed Apr 28, 2004 7:45 pm Mesaj konusu: |
|
|
bi tek o 47 isi biraz kil. bi ihtimal _FILE_ ve _LINE_ makrolariyla satir numarasi verdirilebilir (mi?). Gems'lerden birinde assert icin mi ne bunu yapan bi gem vardi.. bakmak lazim..
saolasin tabe bu arada.. |
|
Başa dön |
|
|
ferdemoncel
Kayıt: Nov 03, 2003 Mesajlar: 277 Nereden: Eskişehir
|
Tarih: Wed Apr 28, 2004 7:59 pm Mesaj konusu: |
|
|
> void sivazla(int * p)
Bu aralar bellekle baya bi ıçlı dışlı olduğum için kodun ne yaptığını merak etmiştim.
Bir de bu belleğin delete ile geri verilmesi yerine Akıllı Göstergeler(Smart Pointers) ve RAII sınıfları kullanılıyormuş.
(RAII = (resource acquisition is initialization) Kaynaklar kurucularda ayrılmalı ve yıkıcılarda geri verilmelidir diye çevirebiliriz )
Nasıl kullanıldığını bilmemekle beraber sanırım Managed C++'deki gibi bir şey herhalde. Napalım artık öğrenecez..
[ Bu mesajı düzenleyen: ferdemoncel _FIL 28-04-2004 22:04 ] |
|
Başa dön |
|
|
sensei
Kayıt: Nov 22, 2002 Mesajlar: 80 Nereden: istanbul
|
Tarih: Wed Apr 28, 2004 8:15 pm Mesaj konusu: |
|
|
evet .. ama. o 47'yi veren crt lib'i.. yani bilmiyom vardir bi yontemi neticede ayni sheyi kendin de yazabilirsin... adamlar oole yazmish .. vardir bi bildikleri diyip birakiyorum ben.. alishinca da kolay oluyo.. zaten genelde neyi unuttugunu tahmin ediyon bi kere hata verince. |
|
Başa dön |
|
|
mentat
Kayıt: Oct 15, 2002 Mesajlar: 528
|
Tarih: Wed Apr 28, 2004 10:09 pm Mesaj konusu: |
|
|
senin ornek cikti zaten baya bi tanidik. yani su kisim;
Detected memory leaks!
Dumping objects ->
{47} normal block at 0x00322F68, 4 bytes long.
Data: < > CD CD CD CD
Object dump complete.
MFC ile debug modda da ayni seyi alabiliyorsun, tek farki orda debug output penceresine yonlendirilmis ve cift tiklayinca o satira, otomatik olarak leak olan satira ziplatiyo seni. yani bi sekilde satir numarasini bulmanin bi yolu vardir herhal (_LINE_ makrosu?) bi iktimal _Crt'li falan bi func.. bakmak lazim.
wxWidget'le debelenmekteyim bu ara, o da ayni ciktiyi debug modun sonunda veriyo paso, ama onda cift tik ise yaramiyo, 47 falan da diyen yok. (bu arada o 47'yi %p ile mi verdiriyo alet? enteresan..) neysem.. uzatmayayim..
ferdo: zamanla o raii'nin hikaye oldugunu goreceksin. onun hikaye oldugu yerlerde tabe smart pointer kullanmak mumkun. ama sistem buyudukce buna benzer birseyler sart. ben bug'siz leak'siz yaziyorum diyen adam mayintarlasindan ote birsey yazmiyodur.. (laf ettim) |
|
Başa dön |
|
|
sensei
Kayıt: Nov 22, 2002 Mesajlar: 80 Nereden: istanbul
|
Tarih: Wed Apr 28, 2004 10:17 pm Mesaj konusu: |
|
|
evet MFC direk olarak yapiyo ama farkli bi CRT lib kullaniyo olabilir (mi ki ?! ) bilmiyorum. bu eger console veya pure win32 app yazacaksaniz tabiii ki.. MFC kodunca boole bishii'ye ihtiyacin olacagini sanmiyom.. ama. gene de DEBUG'da degil de normal MFC'den console achip goreceksen gene bi yol gosterici nasil kullanildigina dair... |
|
Başa dön |
|
|
deniz Site Yöneticisi
Kayıt: Sep 14, 2002 Mesajlar: 838 Nereden: Ankara
|
Tarih: Thu Apr 29, 2004 8:35 am Mesaj konusu: |
|
|
güsel.. peki akabinde konu memleak den açılmışken söyle bir soru soriim..
int main(int argc,char **argv) {
int *ptr = new int[100000];
return 0;
}
gibi bişi yaptığımızda işletim sistemi programın bitiminde bu new ile heap den alloc ettiğimiz bölgeyi otomatik olarak free ediyor değil mi?.. yani heap allocation işleminde sonuçta bizim processe özgü bi heap kullanıldığına göre böyle bi güzelliğide otomatikman yapıyor diye biliyorum.. bu doğrumu?? (en azından winNT, linux gibi işletim sistemlerinde)..
|
|
Başa dön |
|
|
Ziyaretci
Kayıt: Apr 24, 2003 Mesajlar: 287 Nereden: İstanbul
|
Tarih: Thu Apr 29, 2004 9:17 am Mesaj konusu: |
|
|
C kullananlar için, daha basit ve az fonksiyonel MEMLEAK kontrolü:
// header dosyasına...
#ifdef DEBUG
#define malloc(s) mymalloc(s)
#define free(p) myfree(p)
void * mymalloc( int size ) ;
void myfree( void * p ) ;
#endif
--------------
// C dosyasına
#ifdef DEBUG
int malloccount = 0 ;
/* malloc lar ve free ler karışmasın diye */
#ifdef malloc
#define _tmpmalloc_ malloc
#undef malloc
#endif
#ifdef free
#define _tmpfree_ free
#undef free
#endif
void * mymalloc( int size )
{
static int isFirst = 0 ;
// eğer ilk defa malloc ediyorsak, tam çıkarken çalıştırmak üzere
// checkLeak fonksiyonunu register edelim...
if( !isFirst )
{
isFirst = 1 ;
atexit( checkLeak ) ; // bunu yannış yazmış olabilirim.. syntax i tam aklimda değil...
}
++malloccount ;
return malloc( size ) ;
}
void myfree( void * p )
{
free( p ) ;
--malloccount;
// burada ASSERT ile bi negatiflik kontrolü yapilabilir, ama büyük ihtimalle gerek yok..
}
void checkLeak()
{
if( mallocount != 0 )
{
fprintf(stderr,"Yapılan malloc sayısı free sayısına eşit değil. Kodu kontrol edin. FARK:%d!\n",malloccount);
}
else
{
fprintf(stderr,"LEAK yok!! Tebrikler..\n"
}
}
#ifdef _tmpmalloc_
#define malloc _tmpmalloc_
#undef _tmpmalloc_
#endif
#ifdef _tmpfree_
#define free _tmpfree_
#undef _tmpfree_
#endif
#endif /*DEBUG*/
***********************************
bu programdan çıkarken standart error a kaç tane malloc un free edilmediğini yazıyor.. Tabii bunu _LINE_, _FILE_ ve bir de linked list tutarak geliştirmek mümkün.. böylece her bi malloc un satır numarası kaydedilecek..
en sonunda, program OK olunca, #undef DEBUG falan deyip, tüm hepsinden kurtulcaz..
|
|
Başa dön |
|
|
UzMaN
Kayıt: Jan 29, 2003 Mesajlar: 118 Nereden: Eskişehir
|
Tarih: Thu Apr 29, 2004 12:56 pm Mesaj konusu: |
|
|
int main(int argc,char **argv) {
int *ptr = new int[100000];
return 0;
}
Evet deniz process den cikinca onun space'i aynen iade ediliyo.bu alanda heapde oldugu icin o da iade ediliyor normal olarak.Bu OS dersinin faydası var baya ehueh. |
|
Başa dön |
|
|
DG
Kayıt: Mar 06, 2004 Mesajlar: 351 Nereden: Eskişehir
|
Tarih: Thu Apr 29, 2004 1:10 pm Mesaj konusu: |
|
|
Program sonlandırıldığında heap bölgesinden ayrılmış olan yeri işletim sistemi boşaltır (delete, free). Unix türevi işletim sistemlerinin olmazsa olmazıdır. WinXP bu işi hala biraz garip yapıyor. Mesela: Morrowind'in *yamalanmamış* halini (ki sürekli CTD verip durur) açmadan önce; SD kullanımı 90MB, kullanılabilir fiziksel bellek 120MB. Oyunu 10-15 dakika oynayıp çıktıktan 1-2 dakika sonra: SD kullanımı 120MB, kullanılabilir fiziksel bellek 90MB. 5-6 dakika sonra değerleri yeniden kontrol ettiğimde ilk hali gibi olduğunu gördüm. Zaten bu özellik o ya da bu şekilde işletim sistemlerinde olmasaydı kimse üç sene hiç kapanmadan işleyen işletim sistemi yapamazdı.
void main(void) {
long double *a = new long double[10000000];
getch();
}
Bu satırlardan sonra WinXP'nin kendini toplaması 2 dakikayı buldu (ram: 256MB DDR-333, arka planda başka uygulama çalışmıyor)
|
|
Başa dön |
|
|
leblebi
Kayıt: Jan 05, 2004 Mesajlar: 127 Nereden: q3dm17
|
Tarih: Thu Apr 29, 2004 5:45 pm Mesaj konusu: |
|
|
Code:
|
void main(void) {
long double *a = new long double[10000000];
getch();
}
|
|
Bende bu kod hic zaman almadan calisti ve kapandi. Baslayinca hafiza kullanimi 80MB artti, kapatinca pat diye 80MB azaldi.
Merak ettim 800MB denedim, o da ayni sekilde, hic sorun olmadan allocate ve deallocate etti (demek ki virtual memory'e access etmedikce allcocate etmek sorun olmuyomus). Makine'nin RAM'i 512MB, WinXP.
Seninkinde niye oyle oldu acaba?
Bu arada Deniz, bu olayin calisip calismadigini Task Manager'dan kontrol edebilirsin. Performance tabina baktiginda orada o anki hafiza durumu gorunuyo.
Bir de perfmon.exe diye windows'la gelen bi program var(Run->perfmon). Bu program memory ve resource larla ilgili bayagi faydali bi debug programi. Bi yerlerde bununla ilgili bi tutorial vardi ama su an bulamadim.
|
|
Başa dön |
|
|
sensei
Kayıt: Nov 22, 2002 Mesajlar: 80 Nereden: istanbul
|
Tarih: Fri Apr 30, 2004 8:21 pm Mesaj konusu: |
|
|
deniz: bildigim kadari ile yapiyo.. yani hatta yapiyo. .yapmazsa sichar zati..
new int [ALL] deyip sistemi gochertirsin yoksa..
heh.. pek istenen bishii olmasa gerek. |
|
Başa dön |
|
|
|