2011-10-12 10 views
7

मैं की तरह एक गतिशील सरणी है कहते हैं:सी ++ गतिशील सरणी के हटाया जा रहा भाग

int* integers2 = integers + 50; 
delete[] integers2; 

मैं न केवल हैं:

int* integers = new int[100]; 

वहाँ इस तरह के रूप सरणी का ही हिस्सा नष्ट करने के लिए एक रास्ता है सब कुछ 50 और उससे अधिक हटाएं, लेकिन अगर मैं मूल पूर्णांक सरणी पर एक और हटाएं [] को कॉल करता हूं, तो यह केवल स्मृति की सही मात्रा को हटा देगा और मूल रूप से आवंटित राशि और सीईजी गलती को हटाने की कोशिश नहीं करेगा।

मैं ऐसा क्यों करना चाहता हूं: मेरे पास डेटा संरचना है जो सरणी के स्तरों में संरचित है, और मैं इस डेटा संरचना को पूर्ण सरणी से बनाने में सक्षम होना चाहता हूं। इसलिए मैं

int* level1 = integers; 
int* level2 = integers + 50; 
int* level3 = integers + 100; 

लेकिन जब स्तर 3 की आवश्यकता नहीं है, तो डेटा संरचना स्वचालित रूप से [] level3 को हटा देगी। मुझे यह जानने की ज़रूरत है कि यह सही तरीके से व्यवहार करेगा और सरणी में सबकुछ नष्ट नहीं करेगा। यदि ऐसा होगा तो मुझे केवल नए सरणी बनाने और सामग्रियों की प्रतिलिपि बनाने की आवश्यकता है, लेकिन प्रदर्शन कारणों से ऐसा करने से बचना अच्छा होगा।

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

+0

std :: डेक वह है जिसे आप ढूंढ रहे हैं। –

+0

नहीं, इसकी नहीं। असल में जो मैं खोज रहा हूं वह मूल सरणी से मूल्यों की प्रतिलिपि किए बिना सरणी से डेक बनाने का एक तरीका है। – Floss

+0

'std :: deque' स्वचालित रूप से आकार देने वाली एक सरणी की तरह कार्य करता है। एक सीधी अप सरणी का आकार नहीं बदला जा सकता है (जब तक इसे 'मॉलोक' के साथ आवंटित नहीं किया जाता है, और उसके बाद केवल आकार दिया जाता है) –

उत्तर

9

नहीं, यह सही तरीके से व्यवहार नहीं करेगा। आप केवल delete[] पॉइंटर्स देख सकते हैं जो आपको new[] से प्राप्त हुए हैं, अन्यथा परिणाम अपरिभाषित हैं और बुरी चीजें हो सकती हैं।

यदि आपको वास्तव में छोटे होने के लिए सरणी की आवश्यकता है तो आपको एक नया आवंटित करना होगा और सामग्री को मैन्युअल रूप से कॉपी करना होगा।

+0

जानकारी के लिए ठीक है – Floss

0

आमतौर पर जब स्मृति आवंटित की जाती है, तो पॉइंटर से पहले कुछ हाउसकीपिंग सामग्री होती है।

अर्थात houskeeping (सूचक) डेटा

आप होगा गड़बड़ है कि अप।

0
int* integers2 = integers + 50; 
delete[] integers2; 
क्योंकि नए int * पर बनाई गई है, इसलिए 100 int की अंतरिक्ष पूर्णांकों के लिए सौंपा गया है

काम नहीं करेगा, अब integers2 पूर्णांकों की 50 वीं स्थान पर केवल एक सूचक है, इसके बारे में यह करने के लिए आवंटित कोई जगह नहीं है अपने स्वयं, इसलिए डिलीट का उपयोग शेष integers2 को मिटा नहीं देगा, यह केवल अनियमित परिणाम देगा।

आप क्या कर सकते हैं पहले 50 को किसी अन्य सरणी में कॉपी करें, और पिछली सरणी को पूरी तरह हटा दें।

हटाएं केवल उस पॉइंटर को हटा दें जिसमें स्थान दिया गया है, पहले पॉइंटर को आवंटित स्थान पर इंगित करने वाले किसी अन्य पॉइंटर को हटाने के लिए पहले पॉइंटर को आवंटित किसी भी स्थान को हटा नहीं दिया जाएगा।

हटाएं [] integers2 integers1 या किसी अन्य सूचक को निर्दिष्ट किसी भी स्थान को हटा नहीं देगा।

0

डायनामिक आवंटकों (जैसे new) आम तौर पर उन्हें आपके द्वारा दी गई स्मृति की भाग जारी करना पसंद नहीं है।यदि आप <malloc.h> परिभाषित लाइब्रेरी फ़ंक्शंस malloc() और free()new और delete के बजाय realloc() का उपयोग कर सकते हैं, तो आप realloc() का उपयोग कर सकते हैं, हालांकि अधिकांश मामलों में आप आकार अंतर के बारे में परवाह करेंगे, यह वैसे भी आपके लिए कॉपी करने जा रहा है।

गतिशील रूप से आकार देने वाले कंटेनर आम तौर पर आकार बदलने के लिए एक घातीय नियम का उपयोग करते हैं: यदि आप अंतरिक्ष से बाहर हो जाते हैं, तो वे आवंटन को डबल करते हैं (और पुराने डेटा को प्रतिलिपि बनाते हैं), यदि आप डेटा का उपयोग करते समय हटाते हैं (उदाहरण के लिए) आधे आवंटन से कम वे एक छोटे आवंटन में प्रतिलिपि बनाएँ। इसका मतलब है कि आप कभी भी आधा मेमोरी बर्बाद नहीं करते हैं, और प्रति तत्व जोड़ा या हटाए गए प्रतिलिपि की लागत प्रभावी ढंग से स्थिर होती है। यह सब लागू करना गधे में दर्द है, हालांकि, बस std::vector का उपयोग करें और इसे आपके लिए करने दें :)।

+0

एक std :: वेक्टर का उपयोग करने से मेरी मूल समस्या हल नहीं होती है। मैं एक कारण के लिए एक गतिशील आकार बदलने वाली सरणी (यानी वेक्टर) की बजाय सरणी के एक टायर सेट का उपयोग कर रहा था। समस्या यह नहीं है कि यह कैसे संग्रहीत किया जाता है, लेकिन मैं एक वेक्टर या गतिशील सरणी रखने के लिए एक आसान तरीका बनाने की कोशिश कर रहा था, बिना मूल डेटा संरचना – Floss

+0

से सभी सामग्री की प्रतिलिपि बनाने की आवश्यकता के बिना @ फ्लॉस: 'सरणी के टायर सेट' क्या है? सरणी के सरणी? और 'वेक्टर :: डेटा() 'के साथ क्या गलत है? –

0

नहीं, आप new[] के साथ आवंटित एक निश्चित आकार वाली सरणी के साथ ऐसा नहीं कर सकते हैं। यदि आप एक गतिशील सरणी चाहते हैं तो एसटीएल कंटेनरों में से एक का उपयोग करें, जैसे कि std::vector

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