2013-05-08 12 views
6

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

SUBROUTINE Cleanup(A) 

    REAL(8), ALLOCATABLE, DIMENSION(:) :: A 

    IF (ALLOCATED(A)) THEN 
     DEALLOCATE(A) 
    END IF 

END SUBROUTINE 

और हर allocatable के लिए "सफाई" कहते हैं:

मेरे वर्तमान दृष्टिकोण पीछा कर रहा है। इसके साथ समस्या यह है कि मेरे सभी चर आयाम -1 नहीं हैं। उनमें से कुछ में मेरे पास तीन आयाम हैं।

मैंने पहले विभिन्न आयामों के लिए 3 अलग-अलग सबराउटिन लिखने और ओवरलोडिंग का उपयोग करने के बारे में सोचा था, लेकिन यह बहुत ही सुरुचिपूर्ण प्रतीत नहीं होता है।

फिर यह मेरे दिमाग में आया कि शायद मैं एक तर्ककर्ता को एक्ट्यूवल तर्क ए के बजाय पास कर सकता हूं, लेकिन मैंने गुमराह किया है और ऐसा लगता है कि आप एक लक्ष्य परिवर्तक को एक पॉइंटर को हटा नहीं सकते हैं।

इस बारे में कोई विचार सही तरीके से कैसे करें?

धन्यवाद।

+4

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

+1

मुझे पता है कि फोरट्रान स्वचालित रूप से स्मृति को मुक्त करता है, लेकिन इस मामले में मैं एक डीएल लिख रहा हूं जिसे लैबव्यू से बुलाया जाता है, इसलिए यह स्मृति का प्रबंधन कर रहा है। जब डीएलएल किसी त्रुटि में आता है, तो लैबव्यू अचानक बंद हो जाता है, और यदि मैं फिर से निष्पादित करने का प्रयास करता हूं, तो यह संदेश दिखाएगा: "ऐरे पहले ही आवंटित है" और बंद हो जाता है। इसका मतलब है कि स्मृति को ठीक से हटाया नहीं जा रहा है। – derkomai

+1

नोट: 'असली (8)' 8 बाइट होने की गारंटी नहीं है। 64 बिट्स के लिए एक पोर्टेबल तरीका 'ISO_FORTRAN_ENV',' असली (असली 64) 'का उपयोग करें। –

उत्तर

7

इस मेरे दृष्टिकोण निम्न में से संयोजन का प्रयोग करेंगे:

  • फोरट्रान 95, सभी स्थानीय गैर बचाया allocatable चर है कि जब एक प्रक्रिया खत्म स्वचालित रूप से पुनः आवंटित की जाती रहे आवंटित किए जाते हैं के रूप में। चाहे यह लागू हो, इस पर निर्भर करता है कि आपके डीएलएल को कैसे बुलाया जाता है, और इसलिए आप वास्तव में चीजों की संरचना कर सकते हैं जैसे कि आपके सभी आवंटन सहेजे गए स्थानीय हैं।

  • फोरट्रान 2003 तक - allocatable वास्तविक बहस अभिप्राय (बाहर) के लिए पारित allocatable डमी तर्क स्वचालित रूप से पुनः आवंटित की जाती हो जाएगा (या फोरट्रान 95 + allocatable टी.आर. इस भाषा के स्तर का व्यापक रूप से बनाए रखा फोरट्रान compilers के बीच समर्थित है) से पहले प्रक्रिया निष्पादन शुरू होता है । प्रश्न में आपके क्लीनअप दिनचर्या को केवल डमी तर्क की घोषणा को इंटेंट (आउट) के रूप में जोड़ने की आवश्यकता है और फिर आईएफ परीक्षण या डीलॉकेट की आवश्यकता नहीं है। आपको अभी भी प्रत्येक प्रकार और रैंक के लिए दिनचर्या लिखनी होगी जिसे आपको साफ करने की आवश्यकता है।

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

  • घटकों के रूप में आपके सभी चर के साथ व्युत्पन्न प्रकारों का उपयोग करके एक वैकल्पिक दृष्टिकोण, व्युत्पन्न प्रकार ऑब्जेक्ट को स्वयं आवंटित करना है। जब आपको सफाई करने की आवश्यकता होती है, तो बस उस ऑब्जेक्ट को हटा दें - इसके घटकों को स्वचालित रूप से हटा दिया जाएगा। फोरट्रान 2003 इस प्रकार की घटना से ट्रिगर होने की अंतिम प्रक्रिया के लिए अनुमति देता है यदि आपके पास इस बिंदु पर अतिरिक्त अन्य सफाई है।

एक व्युत्पन्न प्रकार दृष्टिकोण भी आसान कई उदाहरण आपके DLL एक बार (आप बस व्युत्पन्न प्रकार के अनेक वस्तुओं है) पर स्वतंत्र रूप से सक्रिय समर्थन करता है, जो कुछ भी की है करने के लिए बनाता है।

व्युत्पन्न प्रकार दृष्टिकोण के उदाहरण दिए गए:

TYPE MyType 
    REAL, ALLOCATABLE :: variable_one(:) 
    INTEGER, ALLOCATABLE :: variable_two(:) 
    ... 
END TYPE MyType 

अभिप्राय (बाहर) डमी

TYPE(MyType) :: object 
ALLOCATE(object%variable_one(xxx)) 
ALLOCATE(object%variable_two(yyy)) 
... 
IF (things_have_gone_wrong) CALL Cleanup(object) 
... 
SUBROUTINE Cleanup(arg) 
    TYPE(MyType), INTENT(OUT) :: arg 
END SUBROUTINE Cleanup 

ALLOCATABLE वस्तु।

TYPE(MyType), ALLOCATABLE :: object 
ALLOCATE(object) 
ALLOCATE(object%variable_one(...)) 
ALLOCATE(object%variable_two(...)) 

... 
IF (things_have_gone_wrong) DEALLOCATE(object) 
+1

यह बहुत अच्छा काम करता है, बहुत बहुत धन्यवाद! – derkomai

+2

एक और तरीका है मैं इस समस्या को हल करने के लिए मिल गया है पूर्वप्रक्रमक मैक्रो का उपयोग कर रहा है: #define सफाई (ए) यदि (आवंटित (ए)) पुनःआवंटन (ए) जब कहा जाता है, सफाई काम करता है। – derkomai