मेरे डेबियन ग्नू / लिनक्स 9 सिस्टम पर, जब एक बाइनरी निष्पादित किया जाता है,
- स्टैक असमान है लेकिन
- ढेर शून्य-प्रारंभिक है।
क्यों?
मुझे लगता है कि शून्य-आरंभीकरण सुरक्षा को बढ़ावा देता है लेकिन, यदि ढेर के लिए है, तो स्टैक के लिए भी क्यों नहीं? क्या ढेर भी सुरक्षा की जरूरत नहीं है?
जहां तक मैं जानता हूं, मेरा प्रश्न डेबियन के लिए विशिष्ट नहीं है।
नमूना सी कोड:
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
const size_t n = 8;
// --------------------------------------------------------------------
// UNINTERESTING CODE
// --------------------------------------------------------------------
static void print_array(
const int *const p, const size_t size, const char *const name
)
{
printf("%s at %p: ", name, p);
for (size_t i = 0; i < size; ++i) printf("%d ", p[i]);
printf("\n");
}
// --------------------------------------------------------------------
// INTERESTING CODE
// --------------------------------------------------------------------
int main()
{
int a[n];
int *const b = malloc(n*sizeof(int));
print_array(a, n, "a");
print_array(b, n, "b");
free(b);
return 0;
}
आउटपुट:
a at 0x7ffe118997e0: 194 0 294230047 32766 294230046 32766 -550453275 32713
b at 0x561d4bbfe010: 0 0 0 0 0 0 0 0
सी मानक malloc()
स्मृति को आवंटित करने से पहले स्पष्ट करने के लिए नहीं कहता है, बेशक, लेकिन मेरा सी कार्यक्रम केवल चित्रण के लिए है। प्रश्न C के बारे में या C के मानक पुस्तकालय के बारे में प्रश्न नहीं है। बल्कि, यह सवाल एक सवाल है कि कर्नेल और / या रन-टाइम लोडर ढेर क्यों नहीं, बल्कि स्टैक को शून्य कर रहे हैं।
अन्य विशेषज्ञ
मेरा प्रश्न मानकों के दस्तावेजों की आवश्यकताओं के बजाय अवलोकन योग्य GNU / Linux व्यवहार का संबंध है। यदि अनिश्चित है कि मेरा क्या मतलब है, तो इस कोड को आज़माएं, जो आगे अपरिभाषित व्यवहार ( अपरिभाषित, यानी जहां तक सी मानक का संबंध है) को इंगित करने के लिए आमंत्रित करता है :
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
const size_t n = 4;
int main()
{
for (size_t i = n; i; --i) {
int *const p = malloc(sizeof(int));
printf("%p %d ", p, *p);
++*p;
printf("%d\n", *p);
free(p);
}
return 0;
}
मेरी मशीन से आउटपुट:
0x555e86696010 0 1
0x555e86696010 0 1
0x555e86696010 0 1
0x555e86696010 0 1
जहां तक सी मानक का संबंध है, व्यवहार अपरिभाषित है, इसलिए मेरा प्रश्न सी मानक का संबंध नहीं है। कॉल को malloc()
हर बार एक ही पते पर वापस नहीं करने की आवश्यकता होती है, लेकिन चूंकि यह कॉल malloc()
वास्तव में हर बार एक ही पते पर लौटने के लिए होती है, इसलिए यह ध्यान रखना दिलचस्प है कि मेमोरी, जो कि ढेर पर है, हर बार शून्य हो जाती है।
इसके विपरीत, स्टैक शून्य नहीं लग रहा था।
मुझे नहीं पता कि आपके मशीन पर बाद का कोड क्या करेगा, क्योंकि मुझे नहीं पता कि GNU / Linux सिस्टम की कौन सी परत में मनाया गया व्यवहार है। आप इसे आजमा सकते हैं।
अपडेट करें
@ कुसलानंद ने टिप्पणियों में देखा है:
इसके लायक क्या है, आपका सबसे हालिया कोड OpenDD पर चलने पर अलग-अलग पते और (कभी-कभी) अनइंस्टाल्यूटेड (गैर-शून्य) डेटा लौटाता है। यह स्पष्ट रूप से उस व्यवहार के बारे में कुछ नहीं कहता है जिसे आप लिनक्स पर देख रहे हैं।
कि मेरा परिणाम OpenBSD पर परिणाम से अलग है वास्तव में दिलचस्प है। जाहिरा तौर पर, मेरे प्रयोग एक कर्नेल (या लिंकर) सुरक्षा प्रोटोकॉल की खोज नहीं कर रहे थे, जैसा कि मैंने सोचा था, लेकिन एक सामान्य कार्यान्वयन कलाकृतियों।
इस प्रकाश में, मेरा मानना है कि, एक साथ, @mosvy, @StephenKitt और @AndreasGrapentin के उत्तर मेरे प्रश्न का समाधान करते हैं।
स्टैक ओवरफ्लो पर भी देखें: मॉलोक 0 में मानों को प्रारंभिक क्यों करता है? (credit: @bta)
new
सी में ऑपरेटर ++ (भी "ढेर") लिनक्स पर सिर्फ malloc के लिए एक आवरण () है; कर्नेल को पता नहीं है और न ही परवाह है कि "ढेर" क्या है।