2010-06-03 20 views
6

ठीक है previous प्रश्न का उत्तर स्पष्ट रूप से दिया गया था, लेकिन मुझे एक और समस्या मिली।सी ++ नया और हटाएं और स्ट्रिंग और फ़ंक्शंस

क्या होगा यदि मैं कार्य करें:

char *test(int ran){ 
    char *ret = new char[ran]; 
    // process... 
    return ret; 
} 

और फिर इसे चलाने:

for(int i = 0; i < 100000000; i++){ 
    string str = test(rand()%10000000+10000000); 
    // process... 

    // no need to delete str anymore? string destructor does it for me here? 
} 

तो स्ट्रिंग के लिए चार * परिवर्तित करने के बाद, मैं हटाने बारे में चिंता करने की जरूरत नहीं है?

संपादित करें: के रूप में उत्तर दिया, मैं delete[] करने के लिए प्रत्येक new[] कॉल है, लेकिन मेरे मामले पर अपनी संभव नहीं के बाद से सूचक खो गया है, तो सवाल यह है: मैं कैसे चार स्ट्रिंग के लिए कनवर्ट करते हैं, ठीक?

+0

पुन: संपादित करें ... या तो डॉन पॉइंटर खोना नहीं है (नीचे दिए गए मेरे उत्तर के अनुसार) या (बेहतर अभी भी) सूचक 'नया' नहीं है, स्ट्रिंग को पकड़ने के लिए बस 'std :: string' का उपयोग करें। आप स्मृति आवंटन खुद क्यों करना चाहते हैं? – Johnsyweb

उत्तर

9

यहाँ आप एक [std::]string कोchar* रूपांतरित नहीं हो हैं, लेकिन नकलchar* एक [std::]string करने के लिए।

अंगूठे के नियम के रूप में, प्रत्येक new के लिए delete होना चाहिए।

इस मामले में, आप यह करने के बाद सूचक की एक प्रति और यह delete स्टोर करने के लिए की आवश्यकता होगी:

char* temp = test(rand()%10000000+10000000); 
string str = temp; 
delete[] temp; 
+0

तो मैं char को स्ट्रिंग में सही तरीके से कैसे परिवर्तित करूं? – Newbie

+0

मुझे लगता है कि जब आपको 'char *' से 'std :: string' में कनवर्ट करने के लिए कहा गया था, तो इसका मतलब यह था कि आपको ** char *' की बजाय ** 'std :: string' का उपयोग करना चाहिए, न कि * कन्वर्ट * प्रोग्राम के। – Johnsyweb

+0

क्या ऐसा करने का कोई आसान तरीका हो सकता है? किसी तरह का फ़ंक्शन या कुछ पसंद है, तो इसमें कोड की केवल एक पंक्ति होगी? – Newbie

2

हाँ, हाँ आप करते हैं।

आप उपयोग कर रहे हैं linux/ओएस एक्स,, इस तरह से आप कर सकते हैं delete [] retvalgrind की तरह कुछ स्मृति से जारी

जो आपकी मदद कर सकता है ताकि यह char * के बजाय एक string रिटर्न आप अपने परीक्षण समारोह को बदल सकते हैं पर गौर परीक्षण समारोह में।

या आप परीक्षण में एक स्ट्रिंग का भी उपयोग कर सकते हैं और नए/डिलीट के बारे में चिंता करने की ज़रूरत नहीं है।

+0

तो मुझे उपयोग करना है: हटाएं [] str; ? – Newbie

+0

नहीं, str यह स्वयं का ऑब्जेक्ट है। इस मामले में, आपने नए char [] को पॉइंटर खो दिया है जिसे आपने आवंटित किया है और इसलिए मेमोरी रिसाव होगा क्योंकि आप इसे हटा नहीं सकते हैं। –

3

आप impresison के तहत होने लगते हैं कि एसटीडी में एक char* गुजर :: स्ट्रिंग स्थान आवंटित स्मृति के स्वामित्व स्थानान्तरण। वास्तव में यह सिर्फ एक प्रति बनाता है।

इसे हल करने का सबसे आसान तरीका केवल पूरे कार्य में std :: स्ट्रिंग का उपयोग करना है और इसे सीधे वापस करना है।

std::string test(int ran){ 
    std::string ret; 
    ret.resize(ran - 1); // If accessing by individual character, or not if using the entire string at once. 
    // process... (omit adding the null terminator) 
    return ret; 
} 
+0

+1 पर एक नज़र डालें। उस ने कहा, आपके उदाहरण कोड में एक नाम गुम है ... –

2

आप चाहिए हर new के लिए कॉल delete अन्यथा आप स्मृति रिसाव हो जाएगा। यदि आपने दिखाया है कि आप पॉइंटर को फेंक रहे हैं, तो आपको char* लौटने के रूप में फ़ंक्शन छोड़ना होगा, तो आपको std::string बनाने के लिए दो लाइनों का उपयोग करना होगा ताकि आप char* की delete पर एक प्रतिलिपि बनाए रख सकें।

एक बेहतर समाधान फ़ंक्शन को फिर से लिखने के लिए std::string वापस करने के लिए फिर से लिखना होगा।

2

आप कुछ इस तरह करने की जरूरत है:

for(int i = 0; i < 100000000; i++){ 
    int length = rand()%10000000+10000000; 
    char* tmp = test(length); 
    string str(tmp); 
    delete[length] tmp; 
} 

यह ठीक से आवंटित चार-सरणी हटा देता है।

वैसे, आपको इसे स्ट्रिंग को शून्य-समाप्त करना चाहिए यदि आप इसे इस तरह से बनाते हैं (यानी फ़ंक्शन test), अन्यथा कुछ फ़ंक्शंस आसानी से "भ्रमित" हो सकते हैं और इसके हिस्से के रूप में आपकी स्ट्रिंग के पीछे डेटा का इलाज कर सकते हैं, जो सबसे अच्छे मामले में आपके आवेदन को दुर्घटनाग्रस्त कर देता है, और सबसे खराब मामले में एक मूक बफर ओवरफ्लो बनाता है जो बाद के बिंदु पर अपरिभाषित व्यवहार को जन्म देता है, जो परम डिबगिंग दुःस्वप्न है ...;)

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