मैंने सरणी के अंत में एक संख्या जोड़ने के लिए push_back फ़ंक्शन बनाया है। लेकिन मुझे लगता है कि नीचे इस कोड में लीक होने के कुछ कारण हैं। क्या आप कारणों का पता लगा सकते हैं?
void ElasticArray::push_back(int item){
if(_max_size == _size){
int* tmpArray = nullptr;
tmpArray = new int[_size * 2];
for(int i = 0; i < _size; i++){
tmpArray[i] = _array[i];
}
_array = tmpArray;
_max_size = _size * 2;
delete[] tmpArray;
tmpArray = nullptr;
}
else if(_max_size == 0){
_max_size = 16;
}
if(_max_size > _size){
_array[_size] = item;
_size++;
}
_array[_size] = item;
_size++;
}
2 जवाब
आपका पूरा फ़ंक्शन सभी गलत कोडित है। आपके चरों के कुप्रबंधन के कारण इसमें कई समस्याएं हैं, इस प्रकार एक स्मृति रिसाव, एक बफ़र ओवरफ़्लो, और अपरिभाषित व्यवहार का कारण बनता है।
यदि _max_size
0 है, तो संभवतः _size
भी 0 है (अन्यथा आपके कोड में कहीं और बग हैं), और आप 0 तत्वों को आवंटित करते हैं। _max_size
को कभी भी 16 पर सेट होने का मौका नहीं मिलता। लेकिन अगर, किसी कारण से, _max_size
0 था लेकिन _size
नहीं था, तो _max_size
16 पर सेट हो जाएगा लेकिन _array
को इंगित करने के लिए वास्तव में कुछ भी आवंटित नहीं होगा, जिससे _array
की सामग्री के बाद के उपयोग पर अपरिभाषित व्यवहार हो।
भले ही आपने कुछ आवंटित किया हो, आप _array
पर delete[]
को कॉल करने से पहले _tmpArray
को _array
असाइन कर रहे हैं, जिससे रिसाव हो रहा है। और फिर आप delete[]
को उस मेमोरी पर कॉल करते हैं जिसे आपने अभी-अभी _array
को असाइन किया है, जिससे _array
की सामग्री के बाद के एक्सेस पर अधिक अपरिभाषित व्यवहार होता है।
इससे भी बदतर, भले ही आप सरणी को ठीक से बढ़ा रहे हों, आप प्रत्येक item
को दो बार सरणी में धकेल रहे हैं, क्योंकि if(_max_size > _size)
कोड में उस बिंदु तक हमेशा सत्य होगा (यदि आप बाकी सब कुछ सही ढंग से कर रहे हैं), जो अंततः बफर ओवरफ्लो, स्मृति को दूषित करने का कारण बन जाएगा।
इसके साथ ही, इसके बजाय इसे आजमाएं:
void ElasticArray::push_back(int item){
if ((_max_size == _size) || (_max_size == 0)){
int new_max = (_max_size != 0) ? (_max_size * 2) : 16;
int* tmpArray = new int[new_max];
for(int i = 0; i < _size; ++i){
tmpArray[i] = _array[i];
}
delete[] _array;
_array = tmpArray;
_max_size = new_max;
}
_array[_size] = item;
_size++;
}
आप _array = tmpArray असाइन कर रहे हैं और उसके बाद tmpArrary पर आपकी कॉलिंग डिलीट हो जाती है फिर आप _array तक पहुंच रहे हैं
_array = tmpArray;
_max_size = _size * 2;
delete[] tmpArray;
tmpArray = nullptr;
_array tempArray द्वारा इंगित मेमोरी लोकेशन के प्रारंभ पते को संग्रहीत करता है
उदाहरण: यदि प्रारंभ स्मृति tempArray का स्थान 0x00f39f38 है तो उसके बाद
_array = tmpArray;
_array 0x00f39f38 को भी इंगित करेगा
तो जब आप कॉल करते हैं
delete tmpArray
tmpArray = nullptr;
TempArray शून्य 0x00000000 को इंगित करना शुरू कर देता है लेकिन पता जो _array द्वारा इंगित किया जाता है वह अभी भी 0x00f39f38 है, इसलिए जब आप ऐसा करते हैं
_array[_size] = item;
_size++;
आपको ओएस और कंपाइलर के आधार पर एक अपरिभाषित व्यवहार मिलेगा
सुझाव
Std::vectors का उपयोग करें या _array=tempArray . करते समय एक गहरी प्रतिलिपि करें
संबंधित सवाल
नए सवाल
c++
C ++ एक सामान्य-प्रयोजन प्रोग्रामिंग भाषा है। यह मूल रूप से C के विस्तार के रूप में डिज़ाइन किया गया था और इसमें एक समान सिंटैक्स है, लेकिन यह अब पूरी तरह से अलग भाषा है। C ++ कंपाइलर के साथ संकलित कोड के बारे में प्रश्नों के लिए इस टैग का उपयोग करें। विशिष्ट मानक संशोधन [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] या [C ++ 23], आदि से संबंधित प्रश्नों के लिए संस्करण-विशिष्ट टैग का उपयोग करें। ।