2012-06-11 15 views
8

मैं एक struct है कि इस तरह दिखता है:नि: शुल्क एक एसटीडी द्वारा प्रयुक्त स्मृति :: स्ट्रिंग

struct queue_item_t { 
    int id; 
    int size; 
    std::string content; 
}; 

मैं एक std::vector<queue_item_t> जो एक डेटाबेस क्वेरी से इनमें से कई के साथ आबादी है।

जब प्रत्येक आइटम संसाधित होता है, तो डिस्क से फ़ाइल को पढ़ा जाता है और इसकी सामग्री content स्ट्रिंग सदस्य में डाल दी जाती है। आइटम संसाधित किया गया है (content पार्स किया गया है) और मैं स्ट्रिंग पर .clear() निष्पादित करता हूं ताकि मेरी सभी मेमोरी न खाएं।

हालांकि, यह स्मृति को मुक्त नहीं लगता है। मेरे पास सैकड़ों हजारों वस्तुओं को संसाधित किया जा रहा है और आखिरकार, स्मृति उपयोग उपलब्ध होने से परे बढ़ेगा और लिनक्स द्वारा "आउट ऑफ़ मेमोरी" के कारण एप्लिकेशन को मार दिया गया है।

मैं इन तारों द्वारा उपयोग की गई स्मृति को कैसे मुक्त कर सकता हूं?

+0

क्या आपको संरचना के सदस्य के रूप में 'सामग्री' की आवश्यकता है? आपके स्पष्टीकरण से, ऐसा लगता है कि यह केवल संक्षेप में उपयोग किया जाता है, इसलिए कार्य के लिए एक अस्थायी बेहतर अनुकूल हो सकता है। इसके अतिरिक्त, 'std :: vector' की बजाय' std :: queue' का उपयोग क्यों न करें? –

+0

तथ्य यह है कि आपकी संरचना को 'queue_item_t' कहा जाता है, यह बताता है कि उनमें से वेक्टर किसी प्रकार की कतार का प्रतिनिधित्व करता है। यदि ऐसा है, तो प्रक्रिया के बाद आप कतार से तत्वों को क्यों नहीं हटाते?मैं पूछता हूं क्योंकि यह हो सकता है कि आपकी समस्या का उचित समाधान कहीं और स्थित है। उन्हें नष्ट करना (और उनकी 'सामग्री' स्ट्रिंग) अपने संसाधनों को जारी करने का एक निश्चित तरीका है! तो आपको केवल इस तथ्य से निपटना होगा कि वेक्टर की शुरुआत से हटाना कुशल नहीं है - इसलिए इसके बजाय 'डेक्यू 'का उपयोग करें, या यदि उनके द्वारा संसाधित किए गए आदेश से कोई फर्क नहीं पड़ता है तो प्रक्रिया को विपरीत क्रम में कोई फर्क नहीं पड़ता। –

+0

@SanderDeDycker जो हिस्सा मैं अब कर रहा हूं वह पूरी प्रक्रिया का दूसरा हिस्सा है; सामान्य ऑपरेशन के तहत, डेटा फ़ाइलों से कभी नहीं पढ़ा जाता है, लेकिन इंटरनेट से पुनर्प्राप्त किया जाता है और डेटा को डाउनलोड किए गए प्रत्येक आइटम की 'सामग्री' स्ट्रिंग में सीधे रखा जाता है। लेकिन आप सही हैं, कि विभिन्न परिस्थितियों में, एक अस्थायी चर बेहतर होगा। –

उत्तर

15

std :: स्ट्रिंग और std :: वेक्टर कंटेनर क्षमता (=> कंटेनर मेमोरी जारी न करें) को स्पष्ट() में परिवर्तित नहीं करते हैं। जब भी कॉम्पैक्शन की आवश्यकता होती है तो अस्थायी वस्तु के साथ नीचे की चाल का उपयोग किया जाना चाहिए (आमतौर पर इसकी आवश्यकता नहीं होती है)।

my_queue_item.content.clear(); // clear 
std::string(my_queue_item.content).swap(my_queue_item.content); // compact 
कोड ऊपर

सरल बनाया जा सकता है जब सफाई + संघनन requried रहे हैं:

std::string().swap(my_queue_item.content); 

कुछ स्ट्रिंग कार्यान्वयन कॉपी-ऑन-राइट कर रहे हैं। ऐसी स्ट्रिंग, जब एक से अधिक स्थानों से संदर्भित किया जाता है, तो लिखने पर स्मृति आवंटित किया जाएगा।

+0

-1 मुझे विश्वास नहीं है कि आपकी पहली वाक्य सटीक है। आपको कैसे पता चलेगा कि 'स्पष्ट' में कोई स्मृति जारी नहीं है? यह वास्तव में वास्तव में है। आंतरिक रूप से, एक स्ट्रिंग में 'char *' होता है। जब आप एक स्ट्रिंग के लिए एक अलग मान असाइन करते हैं, तो पुराना एक बदल दिया जाता है। स्मृति रिलीज के बिना, std :: स्ट्रिंग स्मृति को रिसाव करेगा, जो यह नहीं करता है। –

+7

और सी ++ 11 एक 'shrink_to_fit' सदस्य फ़ंक्शन जोड़ता है, जो कुछ समझदार करने के लिए कार्यान्वयन के लिए एक बाध्यकारी अनुरोध है। –

+4

@ लचियन: 'स्पष्ट' की गारंटी है कि स्ट्रिंग की 'क्षमता' को कम न करें, इसलिए यह बहुत अधिक स्मृति मुक्त नहीं कर सकता है। –

1

clearसभी स्ट्रिंग की स्मृति (शायद केवल बफर) मुक्त नहीं होगा। यह सिर्फ स्ट्रिंग को एक खाली पर सेट करेगा।

यदि आप स्ट्रिंग पर clear पर कॉल कर सकते हैं, तो इसका पुन: उपयोग क्यों न करें? तो, एक नया queue_item_t बनाने के बजाय, बस अपने स्ट्रिंग सदस्य को नए मान के साथ प्रतिस्थापित करें।

0

clear स्मृति को जारी नहीं कर सकता है। यह तर्कसंगत रूप से स्ट्रिंग को एक खाली स्ट्रिंग पर सेट करेगा, लेकिन पहले से आवंटित स्मृति को प्रभावित नहीं कर सकता है।

आप एक ही queue_item_t में अधिक डेटा पढ़ रहे हैं, यह पिछले स्ट्रिंग सामग्री को प्रतिस्थापित करना चाहिए।

क्या आप वाकई queue_item_t को लीक नहीं कर रहे हैं? shrink_to_fit() होगा अच्छी तरह से मुक्त स्मृति

my_queue_item.content = ""; 
my_queue_item.content.shrink_to_fit(); 

विधि और my_queue_item.content के नए मूल्य (इस मामले के लिए 15 बाइट्स) के लिए छोटे पर्याप्त जगह आवंटित:

1

मुक्त स्मृति करने के लिए तुम सिर्फ कर सकते हैं।

+1

दुर्भाग्यवश shrink_to_fit() बाध्यकारी नहीं है, इसलिए शायद इसे अनदेखा किया जा सकता है, जिससे यह एक बहुत ही उपयोगी काम हो सकता है जब यह एक बहुत ही उपयोगी काम हो सकता है। –

संबंधित मुद्दे