2010-02-28 15 views
5

मेरी समारोह:: कार्य के बाहर एक स्टैक आवंटित संरचना क्यों मौजूद है?

struct hostent * gethost(char * hostname){ 
    if(/*some condition under which I want 
     to change the mode of my program to not take a host*/){ 
     return null 
    } 
    else{ 
     struct hostent * host = gethostbyname(hostname); 
     return host; 
    } 
} 
मुख्य में

:

struct hostent * host = gethost(argv[2]); 

(कोड में किसी भी मामूली त्रुटियों पर ध्यान न दें, मैं स्मृति से उगल रहा हूँ)

इस ठीक काम करता है। और वालग्रिंड मुझे नहीं बताता कि मैं स्मृति खो रहा हूं, इस तथ्य के बावजूद कि मैं मुक्त नहीं हूं।

क्यों? मैंने सोचा कि स्टैक पर आवंटित सामान फ़ंक्शन कॉल रिटर्निंग के साथ गायब हो जाता है? या ऐसा इसलिए है क्योंकि मैं सूचक लौटाता हूं? क्या यह किसी भी तरह से खतरनाक है?

उत्तर

10

host स्टैक पर आवंटित नहीं किया गया है, केवल इसके लिए एक सूचक स्टैक पर है। फ़ंक्शन लौटने पर पॉइंटर कॉपी हो जाता है, इसलिए कोड के साथ कुछ भी गलत नहीं है।

ध्यान दें कि gethostbyname वास्तव में गतिशील रूप से स्मृति आवंटित नहीं करता है। यह हमेशा स्मृति के समान स्थिर आवंटित ब्लॉक में एक सूचक देता है, यही कारण है कि valgrind एक रिसाव की रिपोर्ट नहीं करता है। हालांकि सावधान रहें, क्योंकि इसका मतलब है कि आपको hostent को अपने फ़ंक्शन द्वारा लौटाया जाना है यदि आप बाद में मान को सहेजना चाहते हैं क्योंकि gethost पर आगे की कॉल इसे ओवरराइट कर देगी।

+0

आह बहुत बहुत धन्यवाद। तो यह 'gethostbyname' के लिए अद्वितीय है? अगर मैंने इसे 'char *' के लिए किया है, उदाहरण के लिए, उस सरणी में मान बाद में ओवरराइट हो सकते हैं? मेरा प्रोग्राम केवल प्रति होस्ट एक मेजबान से निपटना है, इसलिए यह ठीक होना चाहिए। –

+0

क्या किसी पॉइंटर द्वारा इंगित मूल्य को बाद में कॉल पर ओवरराइट किया जाता है, उस फ़ंक्शन पर निर्भर करता है जिसे आप कॉल कर रहे हैं। किसी भी सी मानक लाइब्रेरी फ़ंक्शन के लिए जो एक पॉइंटर लौटाता है जिसे आप पास नहीं करते हैं, आप मान सकते हैं कि यह स्थिर स्मृति में पॉइंटर लौटा रहा है और इसे ओवरराइट किया जा सकता है। – Gabe

0

वैसे स्मृति को तब तक लीक नहीं किया जाता है जब तक कि इसके सभी संदर्भ गुम हो जाते हैं, आपके उदाहरण में सूचक वापस लौटाया जाता है, इसलिए अभी भी इसका संदर्भ है।

हालांकि, यह गतिशील स्मृति को जारी करने के लिए कोड के किसी अन्य भाग पर भरोसा करने के लिए ज्यादातर मामलों पर खराब डिजाइन निर्णय है। यदि फ़ंक्शन को उदाहरण के लिए एक स्ट्रक्चर वापस करने की आवश्यकता है, तो कॉलर को ऐसा करना चाहिए और संरचना में पॉइंटर पास करना चाहिए।

+2

स्मृति लीक नहीं है क्योंकि 'gethostbyname' गतिशील आवंटन नहीं करता है। यह हर बार एक स्थिर सूचक देता है। – Gabe

+2

और कौन बताता है, इस सूचक पर संदर्भ ट्रैक करता है?:) – vladr

+2

पॉइंटर के संदर्भ में कोई भी संदर्भ ट्रैक नहीं करता है। सॉकेट लाइब्रेरी लोड होने पर स्मृति की ब्लॉक आवंटित की जाती है और प्रक्रिया समाप्त होने तक सॉकेट लाइब्रेरी को अनलोड नहीं किया जाता है। – Gabe

2
पुस्तिका से

:

RETURN VALUE 
     The gethostbyname() and gethostbyaddr() functions return the hostent 
     structure or a NULL pointer if an error occurs. On error, the h_errno 
     variable holds an error number. When non-NULL, the return value may 
     point at static data, ... 

कुछ स्मृति संकलन समय (यानी बाइनरी कोड के अंदर।) संरचना के लिए, समारोह इस स्मृति के लिए सूचक रिटर्न पर आरक्षित है।

3

यह ठीक है और रिसाव करता है क्योंकि लौटा हुआ पॉइंटर स्टैक या ढेर पर डेटा इंगित नहीं करता है, लेकिन कुछ स्थैतिक चर।

http://linux.die.net/man/3/gethostbyname:

कार्यों gethostbyname() और gethostbyaddr() स्थिर डेटा है, जो बाद कॉल द्वारा ओवरराइट किया जा सकता है के लिए संकेत वापस आ सकते हैं। संरचना होस्टेंट की प्रतिलिपि पर्याप्त नहीं है, क्योंकि इसमें पॉइंटर्स हैं; एक गहरी प्रति आवश्यक है।

+0

क्यों "वैश्विक"? वैश्विक और स्थैतिक एक ही बात नहीं हैं। – Ben

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