2011-12-15 18 views
5

के बिना एक चार सूचक लौटें पर विचार करें निम्नलिखित कोड:सी - malloc

char* pointerTesting(void) { 

    char* test = "hello"; 
    return test; 
} 

int main() { 

    char* string = pointerTesting(); 
    printf("string: %s\n", string); 
} 

यह कोई समस्या नहीं संकलन है और चल रहा है। हालांकि, मेरी समझ में, यह काम नहीं करना चाहिए, क्योंकि test पॉइंटर आवंटित स्मृति स्टैक पर है और मुख्य पर लौटने पर यह नष्ट हो गया है।

तो सवाल यह है कि यह पॉइंटर टेस्टिंग() फ़ंक्शन में मॉलोक के बिना काम करने का प्रबंधन कैसे करता है?

+3

http://stackoverflow.com/questions/2589949/c-string-literals-where-do-they-go और stackoverflow पर इस विषय पर समान प्रश्नों का एक समूह देखें। – jman

+0

* पॉइंटर * स्टैक (सामान्य कार्यान्वयन के लिए) पर आवंटित किया गया है, लेकिन आप पॉइंटर वापस नहीं कर रहे हैं, केवल इसकी प्रतिलिपि अगर इसकी कीमत है। यह 'int n = 42 के समान है; वापसी एन; '। यह उस प्रासंगिकता के बारे में बताता है जो यह प्रासंगिक है। –

उत्तर

13

इस मामले में, स्ट्रिंग "hello" वैश्विक स्मृति * में संग्रहीत है। तो यह पहले से ही आवंटित है।

इसलिए, जब भी आप फ़ंक्शन से वापस आते हैं तो यह अभी भी वैध है।

हालांकि, अगर आप ऐसा किया:

char test[] = "hello"; 
return test; 

तो नहीं, यह काम नहीं करेगा। (अपरिभाषित व्यवहार) इस मामले में, स्ट्रिंग वास्तव में एक स्थानीय सरणी है - जो फ़ंक्शन लौटने पर अब नहीं रहती है।

* हालांकि यह आमतौर पर मामला है, मानक यह नहीं कहता कि इसे वैश्विक स्मृति में संग्रहीत किया जाना है।
लेकिन महत्वपूर्ण हिस्सा यह है कि एक स्ट्रिंग अक्षर का जीवनकाल पूरे कार्यक्रम की अवधि है। (टिप्पणियां देखें)

+0

यदि आपके उत्तर का उल्लेख है कि "हेलो" 'किसी भी मानक में निर्धारित व्यवहार के कारण कार्यान्वयन के दुर्घटना और _not_ द्वारा वैश्विक स्मृति में है, तो मैं खुश रहूंगा। – sarnold

+0

@ कर्नाल्ड सहमत, क्या मुझे इसे "* आमतौर पर * वैश्विक स्मृति में संग्रहीत" में बदलना चाहिए? या मुझे कहना चाहिए कि "कहीं और * संग्रहीत है"? – Mysticial

+0

मुझे अब आपके द्वारा प्राप्त तारांकन पसंद है। :) धन्यवाद! – sarnold

2

चाल यह है कि परीक्षण द्वारा संदर्भित स्मृति स्टैक पर नहीं है जैसा आप उम्मीद करते हैं। कुछ स्पष्टीकरण के लिए String literals: Where do they go? देखें।

5

आप मूल्य test की, जो स्ट्रिंग में पहले वर्ण का पता शाब्दिक "hello" (जो, सभी स्ट्रिंग शाब्दिक की तरह, इस तरह से char की एक सरणी के रूप में संग्रहीत किया जाता है कि यह उपलब्ध है है लौट रहे हैं कार्यक्रम के जीवनकाल के लिए)। यदि आप बाद में उपयोग के लिए पताtest वापस करने का प्रयास कर रहे थे, तो हाँ, आप समस्याओं में भाग ले रहे होंगे।

अब यह स्निपेट होगा नहीं काम:

char *pointerTesting(void) 
{ 
    char test[] = "hello"; 
    return test; 
} 

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

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