2012-01-01 11 views
30

मैं सी में time.h फ़ाइल के साथ खेल रहा था जो हमें समय/दिन के कार्यों के साथ मदद करता है।सी में आवंटित स्थानीयकरण की परिणाम संरचना कैसी है?

मैं भर में आया था:

struct tm * _Cdecl localtime(const time_t *__timer); 

... जो टीएम struct के सूचक के वापस जाने के लिए लगता है। मैंने पाया है कि पते से वापसी का उपयोग ज्यादातर नई स्मृति आवंटन को वापस करने के लिए किया जाता है।

यदि ऐसा है, तो उपर्युक्त वापसी वास्तव में कैसे काम करती है (struct tm का वापसी पता)। क्या लौटाई वस्तु कहीं परिभाषित है?

धन्यवाद

+0

आप अपने कोड में टीएम स्ट्रक्चर *** को परिभाषित और आवंटित करते हैं। *** localtime() उस संरचना में अपना आउटपुट संग्रहीत करता है और उसी संरचना में एक सूचक देता है। यह अनावश्यक प्रतीत हो सकता है लेकिन कभी-कभी पॉइंटर वापस पाने के लिए यह आसान होता है, भले ही आप जानते हैं कि संरचना कहां है। –

+3

@PeteWilson - उम, नहीं, आप नहीं करते। कृपया नीचे दिए गए उत्तरों को देखें। आप जो वर्णन करते हैं वह कॉल के '_r' संस्करण (' localtime_r() ') में एसएसवीवी 2 या एमएसवीसी –

+0

में कॉल के' _s' संस्करण के संभावित मामले में केवल मामला है [लोकलटाइम की लौटाई गई संरचना() की आवश्यकता है मुक्त हो?] (http://stackoverflow.com/questions/6210880/does-returned-struct-of-localtime-need-to-be- मुक्त) –

उत्तर

37

सूचक localtime (और कुछ अन्य कार्यों) द्वारा दिया वास्तव में स्थिर स्मृति आवंटित की ओर संकेत करती हैं। तो आपको मुक्त करने की आवश्यकता नहीं है। इसके अलावा, आपको इसे मुक्त नहीं करना चाहिए।

http://www.cplusplus.com/reference/clibrary/ctime/localtime/

यह संरचना स्थिर आवंटित और कार्यों gmtime और स्थानीयसमय द्वारा साझा किया जाता। प्रत्येक बार या तो इन कार्यों में से एक कहा जाता है जिसे इस संरचना की सामग्री ओवरराइट की जाती है।

संपादित करें: टिप्पणियों में उल्लिखित कुछ चीजों को जोड़ना।

इस साझा डेटा-संरचना का सीधा परिणाम यह है कि localtime और इसी तरह के कार्य थ्रेड-सुरक्षित नहीं हैं। थ्रेड-सुरक्षित समाधान विभिन्न प्लेटफॉर्म के साथ भिन्न होता है। localtime_r for POSIX और localtime_s for MSVC

+1

+1। यह परेशान है कि सी (99) मानक इस बारे में कुछ भी नहीं कहता है, हालांकि ... –

+5

@OliCharlesworth वास्तव में इसे पढ़ा है, पढ़ा है (सी 99, 7.23.3 समय रूपांतरण कार्य) "स्ट्रैटाइम फ़ंक्शन के अलावा, ये फ़ंक्शन प्रत्येक पॉइंटर को वापस लौटाते हैं दो प्रकार की स्थैतिक वस्तुओं में से एक [...] इन ऑब्जेक्ट प्रकारों में से किसी एक को पॉइंटर लौटने वाले किसी भी कार्य का निष्पादन उसी प्रकार के किसी भी ऑब्जेक्ट में जानकारी को ओवरराइट कर सकता है जो किसी भी पिछले कॉल से लौटाए गए मूल्य से इंगित करता है उनमे से कोई भी।" – ouah

+1

यह भी इंगित करने के लिए अच्छा हो सकता है कि इस वजह से, यह थ्रेडसेफ नहीं है और इन कॉलों के '_r' संस्करण हैं। –

3

असल में localtime आमतौर पर एक स्थिर वस्तु का पता देता है। मुझे लगता है यह इस तरह दिखता है:

struct tm * 
localtime(const time_t *timer) 
{ 
    static struct tm tm; 

    /* Magic. */ 

    return &tm; 
} 
+0

आप एक 'और' मुझे लगता है कि – ChrisWue

+1

@ChrisWue bk1e पहले ही संपादित किया गया है :-) – cnicutar

+0

सी में कोई ऑब्जेक्ट नहीं है :) –

11

यह स्थिर आबंटित स्मृति का एक टुकड़ा (शायद या तो एक static चर या localtime अंदर परिभाषित एक वैश्विक सी क्रम पुस्तकालय में कहीं परिभाषित) के लिए सूचक देता है। आपको ऐसी स्मृति मुक्त नहीं करनी चाहिए।

स्पष्ट रूप से यह फ़ंक्शन पुनर्वित्त नहीं है (लेकिन टीएलएस का उपयोग होने पर थ्रेड-सुरक्षित हो सकता है)।

आप जब इस सूचक का उपयोग कर सावधान रहना चाहिए: कभी नहीं जवाब में (,/... इससे पहले कि आप कि सूचक का उपयोग समाप्त अन्यथा अपने सूचक द्वारा संदर्भित स्मृति की सामग्री को बदल सकता है किसी भी समारोह कॉल कि localtime/gmtime कह सकते हैं बनाने के localtime पर नई कॉल के लिए) और आप time_t के सापेक्ष मूल्य पढ़ रहे होंगे।

सामान्यतः दिनांक/समय पुस्तकालय का डिज़ाइन काफी पुराना है, इस तरह का अनुकूलन सार्थक था जब सी भाषा डिज़ाइन की गई थी, आजकल यह केवल समस्याएं देता है।

इन समस्याओं का समाधान करने के लिए इन कार्यों में से कम से कम दो अलग बेहतर संस्करण हैं: localtime_r (SUSv2, "रैत्रांत" के लिए r रहता है) और localtime_s (माइक्रोसॉफ्ट, "सुरक्षित" के लिए s रहता है)।पोर्टेबिलिटी के लिए दुखद तथ्य यह है कि ये लगभग एक ही चीज करते हैं (उन्हें पैरामीटर के रूप में पारित करने के लिए गंतव्य struct tm की आवश्यकता होती है), लेकिन पैरामीटर के नाम और क्रम में भिन्न होती है।

+0

नोट: 'localtime_s()' सी 11 स्पेक में भी विस्तृत है: मानक अनुभाग K.3.8.2.4। निश्चित नहीं है कि एमएस (या कोई भी) उस सी 11 विनिर्देश को पूरा करता है। – chux

5

man page कहते हैं: एक स्थिर आवंटित struct दिनांक और समय किसी भी कार्य के लिए आगामी कॉल द्वारा ओवरराइट किया जा सकता है जो करने के लिए

वापसी मान इंगित करता है।

इसके अलावा:

localtime_r() फ़ंक्शन एक ही करता है, लेकिन एक उपयोगकर्ता के आपूर्ति struct में डेटा संग्रहीत करता। इसे tzname, timezone, और डेलाइट सेट करने की आवश्यकता नहीं है।

0

localtime फ़ंक्शन द्वारा लौटाए गए पॉइंट ऑब्जेक्ट में स्थिर संग्रहण अवधि है।

3

वे लाइब्रेरी के लिए एक स्थैतिक संरचना स्थानीय में एक सूचक वापस लौटते हैं। मैन पेज से:

NOTES 

The four functions asctime(), ctime(), gmtime() and localtime() return 
a pointer to static data and hence are not thread-safe. Thread-safe 
versions asctime_r(), ctime_r(), gmtime_r() and localtime_r() are spec‐ 
ified by SUSv2, and available since libc 5.2.5. 

POSIX.1-2001 says: "The asctime(), ctime(), gmtime(), and localtime() 
functions shall return values in one of two static objects: a broken- 
down time structure and an array of type char. Execution of any of the 
functions may overwrite the information returned in either of these 
objects by any of the other functions." This can occur in the glibc 
implementation.
+0

+ थ्रेड-सुरक्षित संस्करणों का उल्लेख करने के लिए इसे +1 करें। – Mysticial

+0

मैन पेज एक अद्भुत बात है। उस समय एसओ मुझे नहीं दिखा रहा था कि किसी और ने जवाब दिया था इसलिए मैंने सोचा कि मैं सिर्फ प्रासंगिक दस्तावेज़ पोस्ट करूंगा। –

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