दिलचस्प पोस्ट
java.lang.IncompatibleClassChangeError: ऐप इंजिन में क्लास की तैनाती करना कार्यान्वित करना मैं प्राथमिकता प्रश्न का उपयोग कैसे करूं? किसी यूआरएल में प्रोटोकॉल को उत्तीर्ण करने के लिए एक अग्रणी डबल स्लैश का उपयोग करने के लिए कोई नकारात्मक पहलू है? यानी src = "// domain.com" पायथन धागे एक एकल कोर पर क्रियान्वित सभी वर्तमान लेनदेन के स्तर को कैसे खोजें? वाई-फाई पर एंड्रॉइड एप्लिकेशन चलाएं / इंस्टॉल करें / डीबग करें? क्या चारों ओर हस्ताक्षरित या हस्ताक्षरित डिफ़ॉल्ट रूप से? कौन सा HTML पार्सर सबसे अच्छा है? क्यूटी क्रिएटर में पथ कैसे शामिल करें? Git एक्सटेंशन: Win32 त्रुटि 487: साइगविन के ढेर, Win32 त्रुटि 0 के लिए स्थान आरक्षित नहीं किया जा सका स्विफ्ट कंपाइलर त्रुटि: स्ट्रिंग संयोजन पर "अभिव्यक्ति बहुत जटिल" सोलर बनाम इलास्टिक खोज पहले किसी लोकल व्हेरिएबल को निर्दिष्ट किए बिना, किसी फ़ंक्शन द्वारा MATLAB सरणी को कैसे लौटाया जा सकता है? उत्पादन में डॉकर कंटेनरों को कैसे स्केल किया जाए सी + + एचटीएमएल टेम्पलेट फ्रेमवर्क, टेम्पलेटिंग लाइब्रेरी, एचटीएमएल जेनरेटर लाइब्रेरी

क्यों malloc जीसीसी में 0 के लिए मूल्यों को प्रारंभ करता है?

शायद यह प्लेटफॉर्म से लेकर प्लेटफॉर्म तक अलग है, लेकिन

जब मैं जीसीसी का उपयोग कर संकलित करता हूं और नीचे कोड चलाता हूं, तो मुझे हर बार 0 ubuntu 11.10 में मिलता है

#include <stdio.h> #include <stdlib.h> int main() { double *a = (double*) malloc(sizeof(double)*100) printf("%f", *a); } 

क्यों malloc ऐसा व्यवहार करते हैं, हालांकि वहाँ कॉलोक है?

क्या इसका अर्थ यह नहीं है कि मूल्यों को 0 से प्रारंभ करने के लिए सिर्फ अवांछित प्रदर्शन का ओवरहेड है, भले ही आप इसे कभी-कभी नहीं चाहें?


संपादित करें: ओह, मेरा पिछला उदाहरण इनिटियाज़लिंग नहीं था, लेकिन "ताजा" ब्लॉक का उपयोग करने के लिए हुआ

मैं वास्तव में क्या देख रहा था यही वजह थी कि जब यह एक बड़ा ब्लॉक आवंटित करता है,

 int main() { int *a = (int*) malloc(sizeof(int)*200000); a[10] = 3; printf("%d", *(a+10)); free(a); a = (double*) malloc(sizeof(double)*200000); printf("%d", *(a+10)); } OUTPUT: 3 0 (initialized) 

लेकिन यह बताते हुए कि एक सुरक्षा कारण है जब मॉलोकिंग! (इसके बारे में कभी सोचा नहीं)। सुनिश्चित करें कि उसे ताज़ा ब्लॉक, या बड़े ब्लॉक को आवंटित करते समय शून्य में आरंभ करना होगा

वेब के समाधान से एकत्रित समाधान "क्यों malloc जीसीसी में 0 के लिए मूल्यों को प्रारंभ करता है?"

संक्षिप्त जवाब:

ऐसा नहीं है, यह आपके मामले में शून्य होने वाला होता है।
(इसके अलावा आपका परीक्षण केस यह नहीं दिखाता कि डेटा शून्य है। यह केवल दिखाता है कि एक तत्व शून्य है।)


लंबा जवाब:

जब आप malloc() कॉल करते हैं, तो दो में से एक चीज होगी:

  1. यह उस स्मृति को पुन: उपयोग करती है जो पिछले आवंटित और उसी प्रक्रिया से मुक्त था।
  2. यह ऑपरेटिंग सिस्टम से नये पेज (पेजों) का अनुरोध करता है

पहले मामले में, स्मृति में पिछले आवंटन से डेटा बचे हुए होगा। तो यह शून्य नहीं होगा। छोटे आवंटन करते समय यह सामान्य मामला है।

दूसरे मामले में, स्मृति ओएस से होगी। यह तब होता है जब कार्यक्रम मेमोरी से बाहर निकलता है – या जब आप बहुत बड़ी आवंटन का अनुरोध कर रहे हों (जैसा आपके उदाहरण में मामला है)

यहाँ पकड़ है: ओएस से आने वाली मेमोरी को सुरक्षा कारणों के लिए चुना जाएगा। *

जब ओएस आपको स्मृति देता है, तो यह एक अलग प्रक्रिया से मुक्त हो सकता था। ताकि स्मृति में संवेदनशील जानकारी हो सकती है जैसे पासवर्ड तो आप इस तरह के डेटा को पढ़ने से रोकने के लिए, इससे पहले कि OS आपको देता है, OS इसे शून्य करेगा।

* मुझे लगता है कि सी मानक इस बारे में कुछ भी नहीं कहता है। यह कड़ाई से एक ओएस व्यवहार है इसलिए इस शून्य को सिस्टम पर मौजूद नहीं हो सकता है या नहीं, जहां सुरक्षा चिंता का विषय नहीं है।


इस पर एक प्रदर्शन पृष्ठभूमि को और अधिक देने के लिए:

@ आर के रूप में टिप्पणियों में उल्लेख है, यह शून्य है इसलिए आपको हमेशा malloc() + memset() बजाय calloc() उपयोग करना चाहिए। calloc() इस तथ्य का लाभ उठा सकते हैं ताकि अलग memset()


दूसरी ओर, यह शून्य भी कभी-कभी एक प्रदर्शन बाधा उत्पन्न होता है। कुछ संख्यात्मक अनुप्रयोगों (जैसे कि आउट-ऑफ-प्लेसमेंट एफएफटी ) में आपको स्क्रैच मेमोरी का एक बड़ा हिस्सा आवंटित करना होगा। जो भी एल्गोरिथ्म को पूरा करने के लिए इसका उपयोग करें, फिर इसे मुक्त करें

इन मामलों में, शून्यिंग अनावश्यक है और शुद्ध ओवरहेड के बराबर है।

मैंने जो सबसे चरम उदाहरण देखा है वह एक 70-सेकंड ऑपरेशन के लिए 20 जीबी स्क्रैच बफर के साथ 20-सेकंड शून्यिंग ओवरहेड है। (मोटे तौर पर 30% ओवरहेड।) (दी गई: मशीन में मेमोरी बैंडविड्थ की कमी थी।)

स्पष्ट समाधान केवल स्मृति को मैन्युअल रूप से पुन: उपयोग करना है। लेकिन वह अक्सर स्थापित इंटरफेस के माध्यम से तोड़ने की आवश्यकता है। (विशेषकर यदि यह एक पुस्तकालय की नियमितता का हिस्सा है)

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

यह असंगत है ठीक क्यों uninitialized चर बग को खोजने के लिए इतनी मेहनत कर रहे हैं।


अवांछित प्रदर्शन ओवरहेड्स के लिए, अनिर्दिष्ट व्यवहार से बचने संभवतः अधिक महत्वपूर्ण है । इस मामले में आप जो भी छोटे प्रदर्शन को बढ़ावा दे सकते हैं, वह उन बगों को खोजने में कठोर क्षतिपूर्ति नहीं करेगा, जिनके साथ आप को निपटाना होगा, यदि कोई व्यक्ति कोड को बदल देता है (पिछली धारणाएं तोड़ रहा है) या किसी अन्य सिस्टम को पोर्ट करता है (जहां मान्यताओं में अवैध हो सकती है पहली जगह में)।

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

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

नोट करें कि malloc() पर glibc मैन पेज कड़ाई से कहते हैं कि स्मृति को मंजूरी नहीं दी गई है, इसलिए एपीआई पर "अनुबंध" के द्वारा, आप यह नहीं मान सकते कि यह साफ हो जाता है। यहां मूल अंश है:

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

यदि आप चाहें, तो आप उस दस्तावेज़ीकरण के बारे में अधिक पढ़ सकते हैं यदि आप प्रदर्शन या अन्य दुष्प्रभावों के बारे में चिंतित हैं।

मैंने आपके उदाहरण को संशोधित किया है जिसमें 2 समान आवंटन शामिल हैं I अब यह देखना आसान है कि malloc मेमोरी शुरू करने में शून्य नहीं करता है।

 #include <stdio.h> #include <stdlib.h> int main(void) { { double *a = malloc(sizeof(double)*100); *a = 100; printf("%f\n", *a); free(a); } { double *a = malloc(sizeof(double)*100); printf("%f\n", *a); free(a); } return 0; } 

जीसीसी 4.3.4 के साथ आउटपुट

 100.000000 100.000000 

मानक यह निर्धारित नहीं करता है कि malloc() को मूल्यों को शून्य में प्रारंभ करना चाहिए। यह सिर्फ आपके प्लेटफ़ॉर्म पर होता है कि इसे शून्य पर सेट किया जा सकता है, या यह उस विशेष समय पर शून्य हो सकता है जब आप उस मूल्य को पढ़ते हैं।

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

Gnu.org से :

इस कार्यान्वयन द्वारा बहुत बड़े ब्लॉक्स (पेज से ज्यादा बड़ा) एमएमएपी के साथ आवंटित किया जाता है (अनाम या अनाम / के द्वारा / देव / शून्य )

क्या आप जानते हैं कि यह निश्चित रूप से शुरू किया जा रहा है? क्या यह संभव है कि मॉलोक () द्वारा लौटा क्षेत्र की शुरुआत में केवल 0 बार ही है?

कभी भी किसी भी कंपाइलर पर भरोसा नहीं करते जो कि कुछ भी करने के लिए स्मृति को इनिशियलाइज़ करेगा malloc बस स्मृति के n बाइट को एक पॉइंटर देता है कहीं नरक यह स्वैप में भी हो सकता है।

यदि मेमोरी की सामग्री महत्वपूर्ण है, तो इसे स्वयं आरंभ करें