मुझे आश्चर्य है कि अगर कोई सी ++ गुरु वहां इस अजीब स्थिति पर कुछ प्रकाश डाल सकता है। बॉक्स 2 डी भौतिकी इंजन के साथ आने वाले उदाहरणों में से एक संदेश "शुद्ध आभासी विधि" नाम से क्रैश हो रहा है, लेकिन केवल एक निश्चित संकलक (और केवल रिलीज निर्माण में) के साथ।स्टैक फ्रेम के भीतर बार-बार इनलाइन कन्स्ट्रक्टर "शुद्ध वर्चुअल विधि" कहा जाता है?
जैसा कि आप जानते हैं बॉक्स 2 डी कोड का एक बहुत ठोस हिस्सा है, इसलिए मुझे लगता है कि यह संकलक के साथ एक समस्या हो सकती है, विशेष रूप से यह केवल यह विशेष संकलक के साथ होता है। मैं Windows7 पर mingw32 उपयोग कर रहा हूँ:
> gcc.exe --version
gcc version 4.4.0 (GCC)
नीचे Box2D के प्रासंगिक भागों का एक कट नीचे अंश है। प्लेसमेंट क्लोन समारोह में नए
b2Shape.h
b2CircleShape.h
b2CircleShape.cpp
SensorTest.h
//base class
class b2Shape
{
public:
virtual ~b2Shape() {}
virtual b2Shape* Clone(b2BlockAllocator* allocator) const = 0;
};
//sub class
class b2CircleShape : public b2Shape
{
public:
b2CircleShape();
b2Shape* Clone(b2BlockAllocator* allocator) const;
};
inline b2CircleShape::b2CircleShape() {}
b2Shape* b2CircleShape::Clone(b2BlockAllocator* allocator) const
{
void* mem = allocator->Allocate(sizeof(b2CircleShape));
b2CircleShape* clone = new (mem) b2CircleShape;
*clone = *this;
return clone;
}
ध्यान दें: आप में पूर्ण स्रोत की जाँच कर सकते हैं।
अब निष्पादन है कि समस्या का कारण बनता है यह करने पर निर्भर करता:
{
b2CircleShape shape;
shape.Clone(allocator); //ok
}
{
b2CircleShape shape;
shape.Clone(allocator); //"pure virtual method called"
}
कैसे एक आभासी विधि कभी पहली जगह में कहा जा सकता है पर अपने आप को शिक्षित करने के बाद, मैं क्यों इसे यहाँ हो रहा था यह पता लगाने की कोशिश की , क्योंकि यह बेस क्लास कन्स्ट्रक्टर में वर्चुअल फ़ंक्शन को कॉल करने के क्लासिक केस में फिट नहीं है। अंधेरे के चारों ओर ठोकर खाने के लंबे सत्र के बाद मैं ऊपर के न्यूनतम मामले के साथ आया था।
मेरा जंगली अनुमान यह है कि संकलक यह देखने के लिए पर्याप्त स्मार्ट है कि इन दो b2CircleShape उदाहरण एक ही दायरे में उपयोग में नहीं हैं, इसलिए यह केवल एक के लिए स्थान आवंटित करता है और इसका पुन: उपयोग करता है। पहले उदाहरण के विनाश के बाद, vtable अपेक्षित है, hosed। फिर किसी कारण से जब दूसरा उदाहरण बनाया गया है, तो vtable फिर से नहीं बनाया गया है ...?
मैं समस्या से बचने वाली दो चीजों के साथ आया, लेकिन जैसा कि मैंने कहा है कि यह एक कंपाइलर समस्या की तरह लगता है, इसलिए मैं यह सुझाव नहीं दे रहा हूं कि इस कोड को बदलने की जरूरत है।
बेसियस फिक्स नंबर 1 बेस क्लास में आभासी विनाशक परिभाषा को टिप्पणी करना है। इस विषय पर मैंने जो सारी जानकारी पढ़ी है, वह बताती है कि यह जवाब नहीं है। (दिलचस्प बात यह है कि मुझे लगता है कि बेस क्लास विनाशक से 'आभासी' संशोधक को हटाने के लिए पर्याप्त नहीं था। मेरी समझ यह है कि संकलक डिफ़ॉल्ट डिस्ट्रक्टर ~ b2Shape() {} प्रदान करेगा यदि कोई निर्दिष्ट नहीं किया गया था, तो परिणाम अलग क्यों है अगर मैं वास्तव में निर्दिष्ट करता हूं कि डिफ़ॉल्ट क्या होगा? अच्छा, यह वास्तव में बिंदु के बगल में है ...)
मुझे पता नहीं था कि उप-वर्ग कन्स्ट्रक्टर से 'इनलाइन' को निकालने के लिए मुझे पता नहीं था । शायद प्लेसमेंट नए, इनलाइन निर्माण और उसी स्टैक फ्रेम में पुन: उपयोग किए गए उदाहरणों के बारे में कुछ है जो अच्छी तरह से एक साथ नहीं खेलता है। (अद्यतन: आगे की जांच प्लेसमेंट को अप्रासंगिक होने के लिए नया दिखाती है)
कुछ और शोध मुझे बताते हैं कि संकलक 'इनलाइन' सुझावों के बारे में जो कुछ भी पसंद करता है उसे करने के लिए स्वतंत्र है, इसलिए शायद अन्य कंपेलरों को यह समस्या नहीं है क्योंकि वे 'इनलाइन' को अनदेखा कर रहे हैं?
क्या आप हमें दिखा सकते हैं कि वास्तव में आवंटक क्या है? क्या आप क्लोन फ़ंक्शन के मूल्य से आवंटक पास करने के किसी भी मौके से हैं? – Arunmu
स्रोत यहां पाया जा सकता है। http://code.google.com/p/box2d/source/browse/trunk/Box2D/Box2D/Common/ ऐसा लगता है कि आवंटक अप्रासंगिक है क्योंकि मैं क्लोन फ़ंक्शन में अधिक विशिष्ट 'नया' का उपयोग कर सकता हूं एक ही परिणाम। – iforce2d
डॉन, सी कोड एक सी ++ छद्म में: x मुझे लगता है कि आप जानते हैं कि आप स्मृति लीक कर रहे हैं? (हां यह अप्रासंगिक है, लेकिन मैं प्रस्तुत कोड में कुछ भी नहीं सोच सकता जो इस तरह के व्यवहार का उत्पादन करेगा)। और एक प्रासंगिक टिप्पणी के लिए: विधि के लिए उत्पन्न असेंबली क्या है? –