2012-06-28 12 views
8

malloc 0'ed स्मृति वापस जाने के लिए गारंटी नहीं है। पारंपरिक ज्ञान न केवल कि है, लेकिन स्मृति की सामग्री को malloc रिटर्न वास्तव में non-deterministic, उदा हैं कि openssl used them for extra randomnessमॉलोक वास्तव में गैर-निर्धारक क्यों है? (लिनक्स/यूनिक्स)

हालांकि, जहां तक ​​मुझे पता है, mallocbrk/sbrk के शीर्ष है, जो "वापसी" कर पर 0'ed स्मृति बनाया गया है। मैं देख सकता हूँ क्यों क्या malloc की सामग्री रिटर्न हो सकता है गैर 0, उदा पहले से मुफ्त 'डी स्मृति से, लेकिन वे "सामान्य" सिंगल-थ्रेडेड सॉफ़्टवेयर में non-deterministic क्यों होंगे?

  1. पारंपरिक ज्ञान वास्तव में सच
  2. (समान द्विआधारी और पुस्तकालयों कल्पना करते हुए) है यदि हां, तो क्यों?

संपादित कई लोगों ने क्यों स्मृति गैर 0, जो मैं पहले से ही ऊपर सवाल में विस्तार से बताया जा सकता है समझाने जवाब दे दिया। मैं जो पूछ रहा हूं वह यह है कि क्यों मॉलोक रिटर्न की सामग्री का उपयोग करने वाला कार्यक्रम गैर-निर्धारिती हो सकता है, यानी हर बार जब यह चल रहा हो तो यह अलग व्यवहार हो सकता है (उसी बाइनरी और पुस्तकालयों को मानते हुए)। गैर-निर्धारक व्यवहार गैर-0 के द्वारा निहित नहीं है। इसे अलग-अलग रखने के लिए: बाइनरी चलाने पर हर बार अलग-अलग सामग्री क्यों हो सकती है।

+1

यदि आप देखते हैं कि यह कभी-कभी गैर-शून्य क्यों हो सकता है, तो आपको पहले ही समझना होगा कि रिटर्न सामान्य रूप से गैर-निर्धारक क्यों है। किसी भी विशिष्ट मामले में यह हमेशा शून्य की स्मृति लौटा रहा प्रतीत होता है, लेकिन सामान्य अर्थ में इसकी गारंटी नहीं दी जा सकती है। – Chad

+0

प्रश्न से संबंधित लिंक कैसा है? –

+0

आप यह भी कह सकते हैं कि सी का उपयोग सामान्य एकल थ्रेडेड सॉफ़्टवेयर के लिए नहीं किया जाता है ... – Mehrdad

उत्तर

2

मुझे लगता है कि यह धारणा है कि यह गैर-निर्धारिती है, खासकर जब आप एक गैर-थ्रेडेड संदर्भ के लिए पूछते हैं। (शेड्यूलिंग एली के कारण थ्रेडेड संदर्भ में आप कुछ गैर-निर्धारिती हो सकते हैं)।

बस इसे आज़माएं। एक अनुक्रमिक बनाएँ, नियतात्मक अनुप्रयोग है कि

  • , कुछ पैटर्न के साथ स्मृति भरता है जैसे यह एक काउंटर
  • मुफ्त के मूल्य के साथ इन आवंटन के हर दूसरे भरने आवंटन की एक पूरी गुच्छा करता
  • नव इन नए आवंटन के माध्यम से एक ही राशि
  • रन का आवंटन और एक फ़ाइल में पहली बाइट का मूल्य रजिस्टर
+०१२३५१६४१०६ (प्रति पंक्ति शाब्दिक संख्या एक के रूप में)

इस कार्यक्रम को दो बार चलाएं और परिणाम को दो अलग-अलग फाइलों में पंजीकृत करें। मेरा विचार यह है कि ये फाइलें समान होंगी।

+0

यही वही है जो मैं उम्मीद करता हूं: जबकि आप नहीं जानते कि प्रोग्राम क्या आउटपुट करेगा, यह हर बार एक ही चीज आउटपुट करेगा (उसी बाइनरी/लाइब्रेरी/सिस्टम को मानते हुए), इसलिए यह निर्धारक होगा। मैं कम से कम अभी तक इस उत्तर को स्वीकार करने जा रहा हूं। – Oleg2718281828

+0

यह थोड़ा अलग विषय है (अपरिभाषित व्यवहार), लेकिन तर्क यहां भी लागू होता है (बास्केटबॉल समानता देखें): http://blog.regehr.org/archives/213 – Mehrdad

11

मॉलोक गारंटी अप्रत्याशितता है ... यह भविष्यवाणी की गारंटी नहीं देता है।

उदा। इस बात पर विचार करें कि

return 0; 

मॉलोक का वैध कार्यान्वयन है।

+1

मेहरदाद, मेरा सवाल यह है कि यह निर्धारित करने के बजाए गैर-निर्धारणावाद कहां से आएगा। – Oleg2718281828

+0

ठीक है, और मेरा जवाब यह है कि आपके कार्यान्वयन पर, यह कहीं से भी नहीं आ सकता है। सी मानक सिर्फ आपके कार्यान्वयन के लिए नहीं है। – Mehrdad

+0

मेहरदाद, आप सही हैं, मैं यहां स्पष्ट हो सकता था: "ऐसे मामलों में जब मॉलोक की सामग्री गैर-निर्धारिती है, लिनक्स पर कहें, यह गैर-निर्धारणा कहां से आती है?", लेकिन यह मेरे प्रश्न का उत्तर नहीं देती । – Oleg2718281828

1

यहां तक ​​कि "सामान्य" सिंगल-थ्रेडेड प्रोग्राम्स में भी, स्मृति को कई बार मुक्त किया जाता है और फिर से आवंटित किया जाता है। मॉलोक आपको उस स्मृति में वापस लौटाएगा जिसका आपने पहले उपयोग किया था।

+0

नेड, हां, मैं इसका उल्लेख करता हूं: "मैं देख सकता हूं कि मॉलोक रिटर्न की सामग्री गैर-0 क्यों हो सकती है ..." – Oleg2718281828

+0

@ ओलेग 2718281828: तब मुझे नहीं पता कि आप क्या पूछ रहे हैं। –

1

यहां तक ​​कि सिंगल-थ्रेडेड कोड मॉलोक भी कर सकता है, फिर मॉलोक को मुक्त कर सकता है और पहले इस्तेमाल किया गया, गैर-शून्य स्मृति वापस प्राप्त कर सकता है।

3

malloc कई प्रणालियों पर परिभाषित किया गया है जिन्हें सी/सी ++ में प्रोग्राम किया जा सकता है, जिसमें कई गैर-यूनिक्स सिस्टम और ऑपरेटिंग सिस्टम की कमी वाले कई सिस्टम शामिल हैं। स्मृति को शून्य करने के लिए malloc की आवश्यकता है सीपीयू को जितना संभव हो सके सीपीयू को बचाने के दर्शन के खिलाफ चला जाता है।

मानक शून्यिंग कैल calloc प्रदान करता है जिसका उपयोग आपको स्मृति को शून्य करने की आवश्यकता होने पर किया जा सकता है। लेकिन ऐसे मामलों में जब आप इसे जितनी जल्दी हो सके स्मृति को शुरू करने की योजना बना रहे हैं, तो CPU चक्रों ने यह सुनिश्चित करने में बिताया कि ब्लॉक शून्य हो गया है; सी मानक का उद्देश्य इस कचरे से जितना संभव हो उतना संभव है, अक्सर पूर्वानुमान की कीमत पर।

1

कोई गारंटी नहीं है कि brk/sbrk वापसी 0-आउट डेटा; यह एक कार्यान्वयन विस्तार है। यह आम तौर पर एक OS करने के लिए है कि यह है कि एक प्रक्रिया से संवेदनशील जानकारी किसी अन्य प्रक्रिया में अपना रास्ता पाता है, लेकिन विनिर्देश में कुछ भी नहीं कहना है कि यह मामला हो जाएगा संभावना को कम करने के लिए एक अच्छा विचार है।

इसके अलावा, /sbrk के शीर्ष पर कार्यान्वित किया गया है, यह भी कार्यान्वयन-निर्भर है, और आवंटन के आकार के आधार पर भी भिन्न हो सकता है; उदाहरण के लिए, लिनक्स पर बड़े आवंटन ने पारंपरिक रूप से mmap पर/dev/zero पर प्रयोग किया है।

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

4

प्रारंभिक मान अनिर्दिष्ट, जिसका अर्थ है कि C और C++ भाषाओं के विनिर्देशों कोई प्रतिबंध नहीं क्या पर मान वापस सौंप दिया जा सकता है डाल रहे हैं। यह विभिन्न प्लेटफॉर्म पर भाषा को कार्यान्वित करना आसान बनाता है। हालांकि यह सच हो सकता है कि लिनक्स malloc में brk और sbrk के साथ कार्यान्वित किया गया है और स्मृति को शून्य किया जाना चाहिए (मुझे यह भी सुनिश्चित नहीं है कि यह आवश्यक रूप से सच है, अन्य प्लेटफॉर्म पर, शायद एक एम्बेडेड प्लेटफ़ॉर्म पर, कोई नहीं है कारण यह है कि यह मामला होना होगा। उदाहरण के लिए, एक एम्बेडेड डिवाइस मेमोरी को शून्य नहीं करना चाहता है, क्योंकि ऐसा करने से CPU चक्र और इस प्रकार बिजली और समय खर्च होता है। इसके अलावा, दक्षता के हित में, उदाहरण के लिए, मेमोरी आवंटक उन ब्लॉक को रीसायकल कर सकता था जिन्हें पहले उन्हें बिना शून्य के मुक्त किया गया था। इसका मतलब है कि भले ही ओएस से स्मृति प्रारंभ में शून्य हो गई हो, भले ही malloc की मेमोरी न हो।

परंपरागत ज्ञान कि मूल्य नोडेटर्मेनिस्टिक है, शायद यह एक अच्छा है क्योंकि यह आपको यह महसूस करने के लिए मजबूर करता है कि आपके द्वारा वापस आने वाली किसी भी मेमोरी में कचरा डेटा हो सकता है जो आपके प्रोग्राम को क्रैश कर सकता है। उस ने कहा, आपको यह नहीं मानना ​​चाहिए कि मूल्य वास्तव में यादृच्छिक हैं। हालांकि, आपको यह महसूस करना चाहिए कि वापस दिए गए मूल्य जादूगर रूप से आप जो चाहते हैं वह नहीं होने चाहिए। आप उन्हें सही तरीके से स्थापित करने के लिए ज़िम्मेदार हैं। मूल्यों को मानना ​​वास्तव में यादृच्छिक है वास्तव में एक बुरा विचार है, क्योंकि यह सुझाव देने के लिए कुछ भी नहीं है कि वे होंगे।

यदि आप स्मृति चाहते हैं जो शून्य आउट होने की गारंटी है, तो इसके बजाय calloc का उपयोग करें।

आशा है कि इससे मदद मिलती है!

3

malloc द्वारा लौटाई गई मेमोरी शून्य नहीं है (या बल्कि को शून्य होने के लिए गारंटी नहीं है) क्योंकि इसकी आवश्यकता नहीं है। अपनी खुद की प्रक्रिया 'पता स्थान या पृष्ठ पूल से खींची गई अनियमित स्मृति का पुन: उपयोग करने में कोई सुरक्षा जोखिम नहीं है। आप पहले से ही जानते हैं कि यह वहां है, और आप पहले ही सामग्री जानते हैं। व्यावहारिक अर्थ में सामग्रियों के साथ कोई समस्या नहीं है, क्योंकि आप वैसे भी इसे ओवरराइट करने जा रहे हैं।

Incidentially, स्मृति mallocद्वारा दिया, पहले आवंटन पर ध्यान केंद्रित किया है, क्योंकि एक ऑपरेटिंग सिस्टम कर्नेल एक प्रक्रिया डेटा है कि किसी अन्य प्रक्रिया पहले से स्वामित्व देने का जोखिम वहन नहीं कर सकते। इसलिए, जब ओएस एक नए पृष्ठ में दोष करता है, तो यह केवल एक ही प्रदान करता है जिसे शून्य किया गया है। हालांकि, यह malloc से पूरी तरह से असंबंधित है।

(थोड़ा सा विषय: आपके द्वारा वर्णित डेबियन सुरक्षा चीज़ में यादृच्छिकता के लिए अनियंत्रित स्मृति का उपयोग करने से कुछ और प्रभाव थे। एक पैकेजर जो कोड के आंतरिक कार्यों से परिचित नहीं था और उसे सटीक प्रभावों को नहीं पता था कुछ स्थानों पर, वालग्रिंड ने संभवतः अच्छे इरादे से, लेकिन विनाशकारी प्रभाव के साथ रिपोर्ट की थी। इनमें से "अनियमित स्मृति से यादृच्छिक" था, लेकिन यह अब तक का सबसे गंभीर नहीं था।)

0

सबसे आसान तरीका मैं जवाब डालने के बारे में सोच सकते हैं इस तरह है:

मैं एक भित्ति-चित्र पेंट करने के लिए, मुझे परवाह नहीं है कि क्या यह सफेद या पुराने भित्तिचित्रों के साथ कवर किया है दीवार अंतरिक्ष रहा हूँ, तो क्योंकि मैं इसे प्रमुख बनाने जा रहा हूं और इसे पेंट कर रहा हूं। मुझे केवल यह ख्याल है कि मेरे पास तस्वीर को समायोजित करने के लिए पर्याप्त स्क्वायर फुटेज है, और मुझे परवाह है कि मैं किसी ऐसे क्षेत्र पर चित्रकारी नहीं कर रहा हूं जो किसी और से संबंधित है।

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

-1

कंप्यूटर की यादें के अंदर रहने वाले कार्यक्रमों का एक संपूर्ण पारिस्थितिक तंत्र है और आप उस आदेश को नियंत्रित नहीं कर सकते जिसमें मॉलॉक्स और फ्री हो रहे हैं।

कल्पना कीजिए कि पहली बार जब आप अपना आवेदन और मॉलोक() कुछ चलाते हैं, तो यह आपको कुछ कचरे के साथ एक पता देता है। फिर आपका प्रोग्राम बंद हो जाता है, आपका ओएस उस क्षेत्र को मुफ्त में चिह्नित करता है। एक और कार्यक्रम इसे एक और मॉलोक() के साथ ले जाता है, बहुत सारी चीजें लिखता है और फिर पत्तियां छोड़ देता है। आप अपना प्रोग्राम दोबारा चलाते हैं, ऐसा हो सकता है कि malloc() आपको एक ही पता देता है, लेकिन अब वहां अलग कचरा है, कि पिछले कार्यक्रम ने लिखा होगा।

मुझे वास्तव में किसी भी प्रणाली में malloc() के कार्यान्वयन को नहीं पता है और मुझे नहीं पता कि यह किसी भी प्रकार की सुरक्षा उपाय लागू करता है (जैसे लौटा हुआ पता यादृच्छिक करना), लेकिन मुझे ऐसा नहीं लगता है।

यह बहुत निर्धारक है।

+0

ऑपरेटिंग सिस्टम मूल रूप से मॉलोक को लागू नहीं करते हैं। सी रनटाइम लाइब्रेरी ऑपरेटिंग सिस्टम फ़ंक्शंस के शीर्ष पर ढेर प्रबंधन के कुछ रूपों का उपयोग करती है। सामान्य समकालीन ऑपरेटिंग सिस्टम के लिए फ़ंक्शंस हाथ वापस वर्चुअल मेमोरी और सुरक्षा कारण के लिए उपयोग किया जाता है जो लगभग हमेशा शून्य होने की गारंटी देता है। –

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