2010-06-01 25 views
7

Aşağıdaki kod neden bellek sızıntıları üretiyor anlamıyorum (boost::shared_ptr statik sınıf örneğiyle kullanıyorum). Birisi bana yardım edebilir mi? Küresel nesneler yok ve shared_ptr nesneyi serbest bırakmak için bir şansı var olsun önceC++ statik sınıflar ve shared_ptr bellek sızıntıları

#include <crtdbg.h> 
#include <boost/shared_ptr.hpp> 
using boost::shared_ptr; 

#define _CRTDBG_MAP_ALLOC 
#define NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) 

static struct myclass { 
    static shared_ptr<int> ptr; 

    myclass() { 
     ptr = shared_ptr<int>(NEW int); 
    } 
} myclass_instance; 

shared_ptr<int> myclass::ptr; 

int main() { 
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | 
        _CRTDBG_CHECK_ALWAYS_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)); 
    return 0; 
} 
+0

Parametreler veya liste içinde neden _CrtSetDbgFlag() 'için ikinci bir çağrı var? – sharptooth

+0

İki ifadeyi bir –

+0

ile birleştirmenin bir yolu bulamıyorum. Neden "ya da" dört bayraklı değilsin, ama bunun yerine "veya" liste "işlevini çağırmıyorsun? – sharptooth

cevap

8

- Aşağıdaki kodu paylaşılan işaretçi en azından g ++

#include <iostream> 
#include "boost/shared_ptr.hpp" 
using namespace std; 
using namespace boost; 

struct R { 
    R() { 
     cerr << "ctor" << endl; 
    } 

    ~R() { 
     cerr << "dtor" << endl; 
    } 
}; 

struct A { 
    static shared_ptr<R> ptr; 

    A() { 
    ptr = shared_ptr<R>(new R); 
    } 

}; 

shared_ptr<R> A::ptr; 
static A a; 

int main() { 
} 

O yazdırır ile düzgün çalıştığını göstermektedir:

ctor 
dtor 
+0

+1 test kodu için – neuro

8

Büyük olasılıkla sızıntı tespit edildiğinde, bu yüzden muhtemelen bir yanlış sızıntı var. CRT yanlış pozitif bildiriyor bir tahmin az

11

budur bir bellek sızıntısı. Myclass_instance adlı myclass'ın statik bir örneğini başlatıyorsunuz. Ayrıca "shared_ptr myclass :: ptr" öğesini de başlatıyorsunuz.

Stroustrup [3] 'e göre, statikler tanımlandıkları sıraya göre başlatılır. Bu nedenle, iç mimariyi ilklendiren myclass_instance'ın statik tanımına sahipsiniz. Ancak, sonra shared_ptr için varsayılan yapıcıyı çağıran statik myclass :: ptr tanımına sahip olursunuz.

Bu, klasik statik sipariş verme sorununa bir örnektir. Derleyici, myclass :: ptr'nin aslında başlatılmamış olduğunu düşünür, bu nedenle orijinal shared_ptr'nin yok edilmesi yoktur. Bunun yerine, sadece sızdırıldı.

Bazı türden çıplak bir işaretçiye ihtiyacınız olacak. C++ 11 kullanıyorsanız, Nifty Counter Technique nesnesinin önceden başlatılmış olduğunu belirledikten sonra kendiliğinden hareket eden üçlü bir atama deyimiyle yapabilirsiniz. Oldukça kaba ama işe yarıyor. İşte

C++ 11 bunu yapmak istiyorum nasıl:

#include <crtdbg.h> 
#include <memory> 
using std; 

#define _CRTDBG_MAP_ALLOC 
#define NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) 

// Note that the count could also be a field in an initializer static used in the Nifty Counter 
// Technique covered in many texts. 
static int count = 0; // This gets implicitly initialized to 0 by the executable load into memory. 
static struct myclass { 
    static shared_ptr<int> ptr; 

    myclass() { 
     if (count++ == 0) { 
     ptr = make_shared<int>(0); //initialization 
     } 
    }   
} myclass_instance; 

shared_ptr<int> myclass::ptr = count == 0 ? make_shared<int>(0) : move(myclass::ptr); 

int main() { 
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | 
        _CRTDBG_CHECK_ALWAYS_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)); 
    return 0; 
} 

fazla bilgi için aşağıdakilere bakın:

  1. Lakos, J, 1996, Büyük Ölçekli C++ Yazılım Tasarımı. Bölüm 7.8.1.3, Addison Wesley, Reading, Massachusetts.
  2. Meyers, S, 2005, Etkili C++, Üçüncü Baskı. Madde 4: Nesnelerin kullanılmadan önce başlatıldığından emin olun. Addison Wesley, Reading, Massachusetts.
  3. Stroustrup, B, 2000, C++ Programlama Dili Özel Sürümü. Bölüm 10.4.9, Addison Wesley, Reading, Massachusetts.
+0

1 Bence bu doğru cevap, anon'un daha önceki cevabı, A ve A :: ptr değişkenlerinin farklı olması nedeniyle doğru bir transkripsiyon değildir. –

İlgili konular