c++ - क्या होगा यदि मैं एक बार सी++ में एक सरणी हटा देता हूं, लेकिन इसे कई बार आवंटित करता हूं?




arrays memory (4)

प्रत्येक बार जब मैं ऑपरेटर का उपयोग करता हूं तो सी ++ विभिन्न मेमोरी रिक्त स्थान आवंटित करता है?

हाँ।

क्या ऑपरेटर केवल अंतिम आवंटित cost सरणी को हटा देता है?

हाँ।

आपने दूसरों के लिए एकमात्र पॉइंटर्स खो दिए हैं, इसलिए वे अपरिवर्तनीय रूप से लीक हो गए हैं। इस समस्या से बचने के लिए, पॉइंटर्स को RAII न करें, लेकिन स्वचालित रूप से गतिशील संसाधनों को प्रबंधित करने के लिए RAII का उपयोग करें। std::vector यहां सही होगा (यदि आपको वास्तव में एक सरणी की आवश्यकता होती है, तो आपका उदाहरण केवल एक int पढ़ना और पुनः उपयोग करना जारी रख सकता है)।

मान लीजिए मेरे पास निम्न स्निपेट है।

int main()
{
    int num;
    int* cost;
    while(cin >> num)
    {
        int sum = 0;
        if (num == 0)
          break;

        // Dynamically allocate the array and set to all zeros
        cost = new int [num];
        memset(cost, 0, num);
        for (int i = 0; i < num; i++)
        {
            cin >> cost[i];
            sum += cost[i];
        }
        cout << sum/num;
    }
`  `delete[] cost;
    return 0;
}

हालांकि मैं अपने कोड के लिए जबकि लूप के अंदर delete कथन को स्थानांतरित कर सकता हूं, समझने के उद्देश्यों के लिए, मैं जानना चाहता हूं कि कोड के साथ क्या लिखा जाता है। प्रत्येक बार जब मैं ऑपरेटर का उपयोग करता हूं तो सी ++ विभिन्न मेमोरी रिक्त स्थान आवंटित करता है?

क्या ऑपरेटर केवल अंतिम आवंटित cost सरणी को हटा देता है?


आपके कोड में कोई cost सरणी नहीं है। आपकी कोड cost में एक सूचक है , एक सरणी नहीं है।

आपके कोड में वास्तविक सरणी दोहराए गए new int [num] कॉल द्वारा बनाई गई हैं। नए को प्रत्येक कॉल एक नई, स्वतंत्र, नामहीन सरणी वस्तु बनाता है जो गतिशील स्मृति में कहीं रहता है। नई सरणी, जिसे एक बार new[] द्वारा बनाया गया है, cost सूचक के माध्यम से सुलभ है। चूंकि सरणी नामहीन है , इसलिए cost सूचक आपके पास एकमात्र लिंक है जो new[] द्वारा बनाई गई उस नामहीन सरणी की ओर जाता है। उस नामहीन सरणी तक पहुंचने के आपके पास कोई अन्य साधन नहीं है।

और हर बार जब आप अपने चक्र में उस cost = new int [num] करते हैं, तो आप एक पूरी तरह से नई, अलग सरणी बना रहे हैं, cost से पिछले सरणी में लिंक तोड़ रहे हैं और नए को इंगित करने के लिए cost बना रहे हैं।

चूंकि cost पुरानी सरणी का आपका एकमात्र लिंक था, इसलिए पुरानी सरणी पहुंच से बाहर हो जाती है। उस पुरानी सरणी तक पहुंच हमेशा के लिए खो जाती है। यह एक स्मृति रिसाव बन जाता है।

जैसा कि आपने इसे स्वयं सही ढंग से बताया है, आपकी delete[] अभिव्यक्ति केवल अंतिम सरणी को delete[] - एक cost अंत में इंगित होती है। बेशक, यह केवल तभी सच है यदि आपका कोड कभी भी cost = new int [num] रेखा निष्पादित करता है। ध्यान दें कि आपका चक्र एकल आवंटन किए बिना समाप्त हो सकता है, इस मामले में आप एक अनियमित (कचरा) सूचक को delete[] लागू करेंगे।


प्रत्येक बार जब आप सरणी के लिए नई मेमोरी आवंटित करते हैं, तो पहले आवंटित स्मृति को लीक किया जाता है। अंगूठे के नियम के रूप में आपको जितनी बार आवंटित किया गया है उतनी बार स्मृति मुक्त करने की आवश्यकता है।


मैं दृढ़ता से सलाह देता हूं कि आप एक सी ++ कार्यक्रम में "सी मुहावरे" का उपयोग न करें। std लाइब्रेरी आपके लिए काम करने दें: यही कारण है कि यह वहां है। यदि आप " एन पूर्णांक के एक सरणी (वेक्टर) चाहते हैं," तो यही है कि std::vector क्या है, और यह "बैटरी शामिल है।" आपको "अधिकतम आकार निर्धारित करने" या "इसे शून्य पर सेट करने जैसी चीज़ों के साथ बंदर-चारों ओर नहीं होना चाहिए।" आप बस "इस बात " के साथ काम करते हैं , जिनकी आंतरिक कार्यवाही आपको नहीं करना है [जानना है ...] यह जानकर कि यह पहले से ही पूरी तरह से डिजाइन और परीक्षण किया गया है।

इसके अलावा, जब आप ऐसा करते हैं, तो आप स्मृति प्रबंधन के लिए सी ++ के मौजूदा ढांचे के भीतर काम कर रहे हैं। विशेष रूप से, आप अपने आवेदन के भीतर "आउट ऑफ़ बैंड" कुछ भी नहीं कर रहे हैं "मानक लाइब्रेरी के बारे में पता नहीं है, और जो इसे (!!) हो सकता है।"

सी ++ आपको तेजी से, कुशल, मजबूत, अच्छी तरह से परीक्षण की कार्यक्षमता की एक बहुत व्यापक पुस्तकालय देता है। इसका लाभ उठाएं





new-operator