डी

2010-10-23 10 views
6

में स्टैक-आधारित ऑब्जेक्ट इंस्टेंटेशन मैं डी सीख रहा हूं, और मुझे जो त्रुटि मिल रही है, उससे उलझन में हूं।डी

module helloworld; 

import std.stdio; 
import std.perf; 

ptrdiff_t main(string[] args) 
{ 
    auto t = new PerformanceCounter; //From managed heap 
    //PerformanceCounter t;    //On the stack 

    t.start(); 
    writeln("Hello, ", size_t.sizeof * 8, "-bit world!"); 
    t.stop(); 

    writeln("Elapsed time: ", t.microseconds, " \xb5s."); 

    return 0; 
} //main() 

एक पूरी तरह से सम्मानजनक पैदावार:

Hello, 32-bit world! 
Elapsed time: 218 µs. 

अब विचार करना क्या जब मैं बजाय प्रबंधित ढेर का उपयोग कर के ढेर पर PerformanceCounter प्रारंभ करने का प्रयास होता है:

निम्नलिखित पर विचार करें

//auto t = new PerformanceCounter; //From managed heap 
PerformanceCounter t;    //On the stack 

उपज:

--- killed by signal 10 

मैं स्टंप हो गया हूं। कोई विचार क्यों यह टूटता है? (मैक ओएस एक्स 10.6.4 पर डीएमडी 2.049)। एन 00 बी की मदद के लिए अग्रिम धन्यवाद।

उत्तर

5

आप डी कक्षाओं के साथ सी ++ कक्षाएं मिश्रण कर रहे हैं।

डी वर्ग हैं हमेशा संदर्भ द्वारा पारित (विपरीत कहते हैं, सी ++ वर्ग), और PerformanceCounter t स्टैक पर वर्ग, केवल इसे करने के लिए एक सूचक का आवंटन नहीं है।

इसका मतलब है कि tnull पर सेट है, ठीक है, null पॉइंटर्स के लिए डिफ़ॉल्ट प्रारंभकर्ता है - इसलिए त्रुटि।

संपादित करें: आप एक सी ++ के Foo* के रूप में डी Foo वर्ग के बारे में सोच सकते हैं।

यदि आप इसे ढेर पर आवंटित करना चाहते हैं, तो आप इसके बजाय structs का उपयोग करने का प्रयास कर सकते हैं - वे कक्षाओं की तरह ही विधियां भी कर सकते हैं। हालांकि, उनके पास विरासत नहीं है।

+0

सुराग के लिए धन्यवाद !! :) (यह समझ में आता है और यह भी जवाब देता है कि ऑब्जेक्ट डिफरेंस/सदस्य ऑपरेटर (->) की आवश्यकता क्यों नहीं है। – anoncow

+0

ठीक है, -> ऑपरेटर को वैसे भी आवश्यक नहीं होगा - उदाहरण के लिए, सी में, कंपाइलर (यदि स्मार्ट पर्याप्त) वास्तव में आपको चेतावनी दे सकता है कि आप गलत ऑपरेटर का उपयोग कर रहे हैं। इसी तरह, डी के पॉइंटर्स (कहें, Foo *) की आवश्यकता नहीं है ->, लेकिन डॉट के साथ काम करें: 'Foo * foo = ; foo.bar = 5; ' –

+0

क्षमा करें, मैं गतिशील रूप से आवंटित ऑब्जेक्ट के लिए इसकी आवश्यकता नहीं कर रहा था, न कि स्टैक-आधारित एक। – anoncow

1

धन्यवाद, टिम।

अपने जवाब के लिए धन्यवाद, मैं http://www.digitalmars.com/d/2.0/memory.html पर निम्न ढूँढने में सक्षम था:


आवंटन कक्षा ढेर पर उदाहरण

कक्षा उदाहरणों सामान्य रूप से कचरा एकत्र ढेर पर आवंटित किए जाते हैं। हालांकि, अगर वे: एक समारोह में स्थानीय प्रतीक के रूप में आवंटित किए जाते हैं नए का उपयोग कर कोई तर्क के साथ नए का उपयोग आवंटित किए जाते हैं (निर्माता तर्क अनुमति दी जाती है) गुंजाइश भंडारण वर्ग तो वे ढेर पर आवंटित कर रहे हैं। यह उदाहरण पर आवंटित/मुक्त चक्र करने से अधिक कुशल है। लेकिन सावधान रहें कि ऑब्जेक्ट का कोई भी संदर्भ फ़ंक्शन की वापसी से बच नहीं पाएगा।

class C { ... } 

scope c = new C(); // c is allocated on the stack 
scope c2 = new C(5); // allocated on stack 
scope c3 = new(5) C(); // allocated by a custom allocator 

वर्ग एक नाशक है, तो है कि नाशक जब वर्ग वस्तु क्षेत्र से बाहर चला जाता है चलाने के लिए गारंटी है, भले ही गुंजाइश एक अपवाद के माध्यम से बाहर निकल गया है।


मेरे कोड अब पढ़ता

scope t = new PerformanceCounter(); //On the stack 

यह (कथित तौर पर) स्टैक पर आवंटित करता और ठीक से चलता है। :)

फिर से धन्यवाद!

+2

जैसा कि उनके पोस्ट में डिस्मिचा बताता है, हालांकि, दायरे को बहिष्करण के लिए निर्धारित किया गया है, इसलिए यह एक अच्छा दीर्घकालिक समाधान नहीं है। –

3

सबसे स्पष्ट उत्तर struct का उपयोग करना है। यदि आप ऐसी लाइब्रेरी का उपयोग कर रहे हैं जिस पर आपके पास नियंत्रण नहीं है या कुछ और ढेर आवंटन एक प्रदर्शन समस्या है, तो आप std.typecons.scoped कार्यक्षमता का उपयोग स्टैक पर वर्ग उदाहरण आवंटित करने के लिए कर सकते हैं। उदाहरण अभी भी संदर्भ द्वारा पारित किया गया है और यदि इसका जीवनकाल वर्तमान स्टैक फ्रेम के जीवनकाल से अधिक है, तो अपरिभाषित व्यवहार का परिणाम होगा। Anoncow के उत्तर के अनुसार scope कीवर्ड काम करेगा, लेकिन डी 2 में बहिष्करण के लिए निर्धारित है।

+0

ओह नहीं! मैं बस गुंजाइश के साथ प्यार में गिर गया था! मैं डी 2 का उपयोग कर रहा हूं, इसलिए मैं पढ़ूंगा कि क्यों, इसे दुखी कर दिया गया है, दुख की बात है। संरचना सुझाव के लिए धन्यवाद - सी ++ की स्टैक आवंटन तंत्र भी उसी गोचा से पीड़ित है। – anoncow

+0

मेरा मानना ​​है कि इसे अनिवार्य रूप से हटा दिया गया है क्योंकि यह असुरक्षित है। स्टैक पर एक कक्षा होने से फ़ंक्शन रिटर्न के बाद इसका संदर्भ रखने का जोखिम चलता है और यह संदर्भ अब मान्य नहीं होता है। यदि यह ढेर पर है, तो यह कचरा नहीं होगा जब तक कि इसके सभी संदर्भ समाप्त नहीं हो जाते हैं, इसलिए आपको वह समस्या नहीं होगी। –

+0

@anoncow: आईआईआरसी, ** स्कोप ** लाइब्रेरी समाधान के साथ बदल दिया गया है। स्मोप्ड की तरह Smth! (YourType) var ** –