स्मृति में मेरे चर C में कहाँ संग्रहीत हैं?


156

यह मानकर कि मेमोरी को चार खंडों में विभाजित किया गया है: डेटा, हीप, स्टैक और कोड, जहां वैश्विक चर, स्थिर चर, निरंतर डेटा प्रकार, स्थानीय चर (कार्यों में परिभाषित और घोषित), चर (मुख्य कार्य में), संकेत हैं , और गतिशील रूप से आवंटित स्थान (मॉलोक और कॉलोक का उपयोग करके) मेमोरी में संग्रहीत होता है?

मुझे लगता है कि उन्हें निम्नानुसार आवंटित किया जाएगा:

  • वैश्विक चर -------> डेटा
  • स्थैतिक चर -------> डेटा
  • लगातार डेटा प्रकार -----> कोड
  • स्थानीय चर (कार्यों में घोषित और परिभाषित) --------> स्टैक
  • चर घोषित और मुख्य कार्य में परिभाषित -----> ढेर
  • संकेत (उदाहरण के लिए ) char *arr, int *arr-------> ढेर
  • डायनामिक रूप से आवंटित स्थान (मॉलॉक और कॉलोक का उपयोग करके) --------> स्टैक

मैं केवल सी परिप्रेक्ष्य से इन चरों का उल्लेख कर रहा हूं।

यदि मैं C के लिए नया हूं तो कृपया मुझे सुधार दें।


4
प्रकार स्मृति में संग्रहीत नहीं हैं।

5
mainबस एक और कार्य है। वेरिएबल्स स्टैक पर चलते हैं जब तक mallocकि कहीं और की तरह नहीं।
सिमोनक

4
पॉइंटर्स (आमतौर पर) स्टैक पर संग्रहीत होते हैं। वे जिस मेमोरी को इंगित करते हैं (आमतौर पर मॉलॉक / कॉलोक के माध्यम से आवंटित किया जाता है) (आमतौर पर) ढेर पर होता है।
jpm

3
गतिशील रूप से आवंटित स्थान (मॉलोक, कॉलोक का उपयोग करते हुए) --------> ढेर
एक आदमी क्रू

3
चर घोषित और मुख्य कार्य में परिभाषित -----> स्टैक
वन मैन क्रू

जवाबों:


217

आपको इनमें से कुछ अधिकार मिल गए, लेकिन जिसने भी लिखा है उसने कम से कम एक प्रश्न पर आपको धोखा दिया है:

  • वैश्विक चर -------> डेटा (सही)
  • स्थिर चर -------> डेटा (सही)
  • निरंतर डेटा प्रकार -----> कोड और / या डेटा। एक ऐसी स्थिति के लिए स्ट्रिंग शाब्दिकों पर विचार करें जब एक स्थिर ही डेटा खंड में संग्रहीत किया जाएगा, और इसके संदर्भ कोड में एम्बेड किए जाएंगे
  • स्थानीय चर (घोषित और कार्यों में परिभाषित) --------> स्टैक (सही)
  • चर घोषित किए गए और mainफ़ंक्शन में परिभाषित किए गए -----> ढेर भी ढेर (शिक्षक आपको छल करने की कोशिश कर रहा था)
  • संकेत (पूर्व: char *arr, int *arr) -------> ढेर डेटा या ढेर संदर्भ के आधार पर। C आपको एक वैश्विक या एक staticपॉइंटर घोषित करने देता है , जिस स्थिति में पॉइंटर स्वयं डेटा सेगमेंट में समाप्त हो जाएगा।
  • गतिशील अंतरिक्ष आवंटित (का उपयोग करते हुए malloc, calloc, realloc) --------> ढेर ढेर

यह ध्यान देने योग्य है कि "स्टैक" को आधिकारिक तौर पर "स्वचालित भंडारण वर्ग" कहा जाता है।


6
यह भी उल्लेखनीय है कि ढेर आधिकारिक तौर पर कुछ भी नहीं कहा जाता है। आवंटित स्मृति कहीं से आती है, उस "कहीं" के लिए मानक में कोई नाम नहीं है।
स्टीव जेसोप

6
कुछ प्रणालियों पर, (जैसे लिनक्स और * बीएसडी) भी है allocaजो समान के समान काम करता है malloc, लेकिन स्टैक आवंटन करता है।
एंड्रियास ग्रेपेंटिन

एक विधि के अंदर घोषित कांस्टेबल चर कहाँ जाते हैं?
महोरी

@ रवी उसी स्थान पर शेष स्थिरांक चलते हैं (बिंदु # 3 ऊपर)।
dasblinkenlight

मैं GCC 4.8.1 का उपयोग कर रहा हूं और यह DATA सेगमेंट में मुख्य के लिए कॉन्स्टेबल वैरिएबल को स्टोर करना प्रतीत नहीं होता है। नीचे 3 ऐसे कार्यक्रमों के लिए कोड और मेमोरी मैप है: कोड 1: int main (शून्य) {// char a [10] = "HELLO"; // 1 // const char a [10] = "HELLO"; // 2 वापसी 0; } मेमोरियल मैप फॉर एबीवीई: टेक्स्ट डेटा बीएसएस डेक्स फ़ाइल नाम हेक्स फ़ाइल नाम 7264 1688 1040 9992 2708 एईजी मेमोरी एमएपी 2 के लिए: टेक्स्ट डेटा बीएसएस डेक्स फ़ाइल नाम 7280 1688 1040 100040 2718 एईएक्स मेमोरी एमएपी 3 के लिए: टेक्स्ट डेटा बीएसएस डेक्स डीएक्स डेक्स फ़ाइल नाम। 7280 1688 1040 10008 2718 a.exe
महोरी

124

उन भविष्य के आगंतुकों के लिए जो उन मेमोरी सेगमेंट के बारे में जानने में दिलचस्पी ले सकते हैं, मैं सी में 5 मेमोरी सेगमेंट के बारे में महत्वपूर्ण बिंदु लिख रहा हूं:

कुछ सिर:

  1. जब भी C प्रोग्राम को निष्पादित किया जाता है, तो प्रोग्राम के निष्पादन के लिए RAM में कुछ मेमोरी आवंटित की जाती है। इस मेमोरी का उपयोग अक्सर निष्पादित कोड (बाइनरी डेटा), प्रोग्राम चर आदि के भंडारण के लिए किया जाता है। नीचे दिए गए मेमोरी सेगमेंट उसी के बारे में बात करते हैं:
  2. आमतौर पर चर तीन प्रकार के होते हैं:
    • स्थानीय चर (C में स्वचालित चर भी कहा जाता है)
    • सार्वत्रिक चर
    • स्थैतिक चर
    • आपके पास वैश्विक स्थिर या स्थानीय स्थिर चर हो सकते हैं, लेकिन उपरोक्त तीन मूल प्रकार हैं।

सी में 5 मेमोरी सेगमेंट:

1. कोड सेगमेंट

  • कोड सेगमेंट, जिसे टेक्स्ट सेगमेंट भी कहा जाता है, मेमोरी का क्षेत्र है जिसमें अक्सर निष्पादित कोड होता है।
  • कोड सेगमेंट को अक्सर रीड-ओनली होने की आशंका से बचने के लिए केवल प्रोग्रामिंग बग्स जैसे बफर-ओवरफ्लो आदि से बचने के लिए किया जाता है।
  • कोड खंड में स्थानीय चर (जैसे C में स्वचालित चर भी कहा जाता है ), वैश्विक चर आदि जैसे कार्यक्रम चर नहीं होते हैं ।
  • सी कार्यान्वयन के आधार पर, कोड खंड में केवल-पढ़ने के लिए स्ट्रिंग शाब्दिक शामिल हो सकते हैं। उदाहरण के लिए, जब आप printf("Hello, world")तब करते हैं तो स्ट्रिंग "हैलो, दुनिया" कोड / टेक्स्ट सेगमेंट में बन जाती है। आप sizeलिनक्स ओएस में कमांड का उपयोग करके इसे सत्यापित कर सकते हैं ।
  • आगे की पढाई

डेटा सेगमेंट

डेटा खंड को दो भागों में विभाजित किया गया है और आमतौर पर ढेर क्षेत्र के नीचे या स्टैक के ऊपर कुछ कार्यान्वयन में निहित है, लेकिन डेटा खंड कभी भी ढेर और स्टैक क्षेत्र के बीच स्थित नहीं होता है।

2. Uninitialized डेटा सेगमेंट

  • इस सेगमेंट को bss के नाम से भी जाना जाता है ।
  • यह स्मृति का वह भाग है जिसमें शामिल हैं:
    1. Uninitialized वैश्विक चर (सूचक चर सहित)
    2. अनधिकृत रूप से निरंतर वैश्विक चर
    3. Uninitialized स्थानीय स्थिर चर
  • कोई भी वैश्विक या स्थैतिक स्थानीय वैरिएबल जो कि इनिशियलाइज़ नहीं है, को अनइंस्टाल्यूटेड डेटा सेगमेंट में संग्रहीत किया जाएगा
  • उदाहरण के लिए: वैश्विक चर int globalVar;या स्थिर स्थानीय चर static int localStatic;को असिंचित डेटा खंड में संग्रहीत किया जाएगा।
  • यदि आप एक वैश्विक वैरिएबल घोषित करते हैं और इसे आरंभ करते हैं 0या NULLफिर अभी भी यह असिंचित डेटा सेगमेंट या bss में जाएगा।
  • आगे की पढाई

3. आरंभिक डेटा खंड

  • यह खंड स्टोर करता है:
    1. प्रारंभिक वैश्विक चर (सूचक चर सहित)
    2. प्रारंभिक वैश्विक चर
    3. आरंभिक स्थानीय स्थिर चर
  • उदाहरण के लिए: वैरिएबल वैरिएबल int globalVar = 1;या स्टैटिक लोकल वैरिएबल static int localStatic = 1;इनिशियलाइज्ड डेटा सेगमेंट में स्टोर किया जाएगा।
  • इस सेगमेंट को आगे प्रारम्भिक पठन-पाठन क्षेत्र और प्रारम्भिक पठन-लेखन क्षेत्र में वर्गीकृत किया जा सकता हैआरंभिक निरंतर वैश्विक वैरिएब इनिशियलाइज्ड रीड-ओनली एरिया में जाएंगे जबकि वे वैरिएबल जिनके मान रनटाइम में संशोधित किए जा सकते हैं, इनिशियलाइज्ड रीड-राइट एरिया में जाएंगे
  • इस खंड का आकार कार्यक्रम के स्रोत कोड में मूल्यों के आकार से निर्धारित होता है, और रन समय पर नहीं बदलता है
  • आगे की पढाई

4. स्टैक सेगमेंट

  • स्टैक सेगमेंट का उपयोग वेरिएबल्स को स्टोर करने के लिए किया जाता है जो फंक्शन के अंदर बनाए जाते हैं ( फंक्शन मेन फंक्शन या यूजर डिफाइन्ड फंक्शन हो सकता है ), वैरिएबल जैसे
    1. समारोह के स्थानीय चर (सूचक चर सहित)
    2. कार्य करने के लिए तर्क पारित किए गए
    3. वापसी का पता
  • फ़ंक्शन निष्पादन समाप्त होते ही स्टैक में संग्रहीत चर हटा दिए जाएंगे।
  • आगे की पढाई

5. ढेर सेगमेंट

  • यह खंड डायनेमिक मेमोरी आवंटन का समर्थन करने के लिए है। प्रोग्रामर सी में गतिशील रूप से तो कुछ स्मृति को आबंटित करना चाहता है यह प्रयोग किया जाता है malloc, callocया reallocतरीकों।
  • उदाहरण के लिए, जब int* prt = malloc(sizeof(int) * 2)आठ बाइट्स को ढेर में आवंटित किया जाएगा और उस स्थान का मेमोरी पता लौटाया जाएगा और उसे ptrचर में संग्रहीत किया जाएगा । ptrचर किसी भी तरह से यह घोषित / प्रयोग किया जाता है पर निर्भर करता है ढेर या डेटा खंड पर होगा।
  • आगे की पढाई

3. आरंभिक डेटा खंड में अनइंस्टॉल किए जाने के बजाय आरंभिक नहीं होना चाहिए।
सूरज जैन

पुन "अप्रारंभीकृत डेटा खंड में संग्रहीत" (कई उदाहरण): क्या आपका मतलब है "डेटा सेगमेंट में अप्रारंभीकृत संग्रहीत" ?
पीटर मोर्टेंसन

@PeterMortensen मेरा मतलब दोनों चीजों से है। "कोई भी वैश्विक या स्थैतिक स्थानीय वैरिएबल जो कि इनिशियलाइज़ नहीं है, को
अनइंस्टाल्यूटेड

हम वैश्विक स्थिर चर C में कैसे हो सकते हैं?

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

11

आपके गलत वाक्यों को ठीक किया

constant data types ----->  code //wrong

स्थानीय स्थिर चर -----> ढेर

आरंभिक वैश्विक निरंतर चर -----> डेटा खंड

uninitialized वैश्विक स्थिर चर -----> bss

variables declared and defined in main function  ----->  heap //wrong

चर घोषित और मुख्य कार्य में परिभाषित -----> स्टैक

pointers(ex:char *arr,int *arr) ------->  heap //wrong

dynamically allocated space(using malloc,calloc) --------> stack //wrong

संकेत (पूर्व: चार * गिरफ्तारी, इंट * गिरफ्तारी) -------> उस सूचक चर का आकार स्टैक में होगा।

विचार करें कि आप गतिशील रूप से n बाइट्स (उपयोग mallocया calloc) की मेमोरी आवंटित कर रहे हैं और फिर इसे इंगित करने के लिए पॉइंटर चर बना रहे हैं। अब nमेमोरी के बाइट्स ढेर में हैं और पॉइंटर चर 4 बाइट्स (यदि 64 बिट मशीन 8 बाइट्स) हैं जो nमेमोरी चंक के बाइट्स के शुरुआती पॉइंटर को स्टोर करने के लिए स्टैक में होंगे ।

नोट: पॉइंटर चर किसी भी सेगमेंट की मेमोरी को इंगित कर सकते हैं।

int x = 10;
void func()
{
int a = 0;
int *p = &a: //Now its pointing the memory of stack
int *p2 = &x; //Now its pointing the memory of data segment
chat *name = "ashok" //Now its pointing the constant string literal 
                     //which is actually present in text segment.
char *name2 = malloc(10); //Now its pointing memory in heap
...
}

गतिशील रूप से आवंटित स्थान (मॉलोक, कॉलोक का उपयोग करके) --------> ढेर


पॉइंटर्स या तो स्टैक या हीप में हो सकते हैं (विशेष रूप से देखें: पॉइंटर्स टू पॉइंटर्स)
argentage

@airza: अब अपडेट किया गया। स्वतः ही मैं उस विवरण को केवल अद्यतन कर रहा था :)
rashok

निम्नलिखित मेमोरी मैप में, क्या आप बता सकते हैं कि ढेर और ढेर कहाँ हैं? मुझे यकीन नहीं है कि यह सही सवाल है क्योंकि स्टैक और मेमोरी केवल रन टाइम पर लागू हो सकती है। मेमोरी एमएपी: "टेक्स्ट डेटा bss dec हेक्स फाइलन 7280 1688 1040 10008 2718 a.exe"
महोरी

7

एक लोकप्रिय डेस्कटॉप आर्किटेक्चर एक प्रक्रिया की वर्चुअल मेमोरी को कई सेगमेंट में विभाजित करता है :

  • पाठ खंड: इसमें निष्पादन योग्य कोड होता है। निर्देश सूचक इस सीमा में मान लेता है।

  • डेटा खंड: इसमें वैश्विक चर (यानी स्थिर लिंकेज वाली वस्तुएं) शामिल हैं। केवल-पढ़ने योग्य डेटा (जैसे स्ट्रिंग स्थिरांक) और अनइंस्टाल्यूटेड डेटा ("बीएसएस") में उपविभाजित।

  • स्टैक सेगमेंट: प्रोग्राम के लिए डायनेमिक मेमोरी, यानी फ्री स्टोर ("हीप") और सभी थ्रेड्स के लिए लोकल स्टैक फ्रेम शामिल हैं। परंपरागत रूप से सी स्टैक और सी ढेर विपरीत छोर से स्टैक सेगमेंट में विकसित होते थे, लेकिन मेरा मानना ​​है कि अभ्यास को छोड़ दिया गया है क्योंकि यह बहुत असुरक्षित है।

एसी प्रोग्राम आम तौर पर वस्तुओं को डेटा स्टोर में स्थिर भंडारण अवधि के साथ डालता है, गतिशील रूप से मुक्त स्टोर पर वस्तुओं को आवंटित करता है, और थ्रेड के कॉल स्टैक पर स्वचालित ऑब्जेक्ट जिसमें यह रहता है।

अन्य प्लेटफार्मों पर, जैसे कि पुराने x86 वास्तविक मोड या एम्बेडेड डिवाइस पर, चीजें स्पष्ट रूप से मौलिक रूप से भिन्न हो सकती हैं।


"मेरा मानना ​​है कि अभ्यास को छोड़ दिया गया है क्योंकि यह बहुत असुरक्षित है" - और धागे को लागू करना असंभव बनाता है, तब से आपको प्रति कार्यक्रम एक से अधिक स्टैक की आवश्यकता होती है और वे सभी अंत में नहीं हो सकते हैं :-)
स्टीव जेसप

@SteveJessop: हाँ, मैं भी यही सोच रहा था। लेकिन धागे लंबे समय से अस्तित्व में हैं - मुझे नहीं पता कि क्या सभी थ्रेड स्टैक भी पीछे की तरफ बढ़े हैं, या अगर वे ढेर की तरह बड़े हो जाएंगे ... वैसे भी, आजकल सब कुछ एक ही दिशा में जाता है और वहां गार्ड होते हैं पृष्ठों की है।
केरेक एसबी

6

मैं केवल सी परिप्रेक्ष्य से इन चरों का उल्लेख कर रहा हूं।

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


3

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

  • एक वैरिएबल जो सभी तक नहीं पहुँचा है, उसे पूरी तरह से समाप्त किया जा सकता है - इसका कोई भंडारण नहीं है ... कहीं भी। उदाहरण - देखें कि 42जनरेट किए गए असेंबली कोड में कैसा है लेकिन कोई संकेत नहीं है404
  • स्वचालित भंडारण अवधि वाला एक चर जिसमें अपना पता नहीं है, को मेमोरी में संग्रहीत करने की आवश्यकता नहीं है। एक उदाहरण एक लूप वेरिएबल होगा।
  • एक चर जो स्मृति में constप्रभावी ढंग से या प्रभावी रूप से constआवश्यक नहीं है। उदाहरण - संकलक साबित कर सकता है कि fooप्रभावी रूप से है constऔर कोड में इसके उपयोग को रेखांकित करता है। barबाहरी लिंकेज है और संकलक साबित नहीं कर सकता है कि यह वर्तमान मॉड्यूल के बाहर नहीं बदला जाएगा, इसलिए यह इनबिल्ड नहीं है।
  • mallocढेर से आवंटित स्मृति में निवास की आवश्यकता के साथ आवंटित एक वस्तु नहीं है! उदाहरण - ध्यान दें कि कैसे कोड में कॉल नहीं है mallocऔर न ही मूल्य 42 मेमोरी में संग्रहीत है, इसे एक रजिस्टर में रखा गया है!
  • इस प्रकार एक ऐसी वस्तु जिसका आवंटन किया गया है mallocऔर वह वस्तु बिना किसी आवश्यकता के वस्तु को हटाए बिना खो जाती हैfree रिसाव स्मृति ...
  • mallocजरूरत के हिसाब से आवंटित की गई वस्तु यूनिक्स पर प्रोग्राम ब्रेक ( ) से नीचे ढेर के भीतर नहीं होनी चाहिए sbrk(0)...

1

संकेत (पूर्व: चार * गिरफ्तारी, इंट * गिरफ्तारी) -------> ढेर

नहीं, वे स्टैक पर या डेटा सेगमेंट में हो सकते हैं। वे कहीं भी इशारा कर सकते हैं।


के बारे में mainऔर गतिशील रूप से आवंटित चर के बयान भी गलत हैं
simonc

केवल स्टैक या डेटा सेगमेंट पर नहीं। एक पॉइंटर के बारे में सोचें जो पॉइंटर्स की एक सरणी की ओर इशारा करता है। इस स्थिति में व्यूह को ढेर पर संग्रहीत किया जाता है।
सेबी 2020

1
  • चर / स्वचालित चर ---> ढेर अनुभाग
  • डायनामिक रूप से आवंटित चर ---> ढेर अनुभाग
  • आरंभिक वैश्विक चर -> डेटा अनुभाग
  • Uninitialised वैश्विक चर -> डेटा अनुभाग (bss)
  • स्थैतिक चर -> डेटा अनुभाग
  • स्ट्रिंग स्थिरांक -> पाठ अनुभाग / कोड अनुभाग
  • कार्य -> ​​पाठ अनुभाग / कोड अनुभाग
  • टेक्स्ट कोड -> टेक्स्ट सेक्शन / कोड सेक्शन
  • रजिस्टर -> सीपीयू रजिस्टर
  • कमांड लाइन इनपुट -> पर्यावरण / कमांड लाइन अनुभाग
  • पर्यावरणीय चर -> पर्यावरण / कमांड लाइन अनुभाग

पर्यावरण / कमांड लाइन अनुभाग क्या है? क्या वे लिनक्स में मौजूद हैं?
Haoyuan Ge

-1

डिस्कनेक्ट विश्लेषण के साथ लिनक्स न्यूनतम रननीय उदाहरण

चूंकि यह एक कार्यान्वयन विवरण है जो मानकों द्वारा निर्दिष्ट नहीं किया गया है, आइए एक नज़र डालते हैं कि संकलक किसी विशेष कार्यान्वयन पर क्या कर रहा है।

इस उत्तर में, मैं या तो उन विशिष्ट उत्तरों से जुड़ूंगा जो विश्लेषण करते हैं, या सीधे यहां विश्लेषण प्रदान करते हैं, और यहां सभी परिणामों को संक्षेप में प्रस्तुत करते हैं।

वे सभी विभिन्न उबंटू / जीसीसी संस्करणों में हैं, और परिणाम संभावित रूप से संस्करणों में बहुत स्थिर हैं, लेकिन यदि हमें कोई भिन्नता मिलती है तो अधिक सटीक संस्करण निर्दिष्ट करें।

एक समारोह के अंदर स्थानीय चर

यह हो mainया कोई अन्य समारोह:

void f(void) {
    int my_local_var;
}

के रूप में दिखाया गया है: क्या करता है <मान बाहर अनुकूलित> जीडीबी में मतलब है?

  • -O0: ढेर
  • -O3: रजिस्टर अगर वे फैल नहीं करते हैं, अन्यथा ढेर

स्टैक मौजूद क्यों है पर प्रेरणा के लिए: x86 असेंबली में रजिस्टरों पर उपयोग किए जाने वाले पुश / पॉप निर्देशों का क्या कार्य है?

वैश्विक चर और staticफ़ंक्शन चर

/* BSS */
int my_global_implicit;
int my_global_implicit_explicit_0 = 0;

/* DATA */
int my_global_implicit_explicit_1 = 1;

void f(void) {
    /* BSS */
    static int my_static_local_var_implicit;
    static int my_static_local_var_explicit_0 = 0;

    /* DATA */
    static int my_static_local_var_explicit_1 = 1;
}

char * तथा char c[]

जैसा कि दिखाया गया है: C और C ++ में स्थिर वैरिएबल कहाँ संग्रहीत हैं?

void f(void) {
    /* RODATA / TEXT */
    char *a = "abc";

    /* Stack. */
    char b[] = "abc";
    char c[] = {'a', 'b', 'c', '\0'};
}

TODO बहुत बड़े स्ट्रिंग शाब्दिक भी स्टैक पर रखा जाएगा? या .data? या संकलन विफल हो जाता है?

तर्क वितर्क

void f(int i, int j);

प्रासंगिक कॉलिंग कन्वेंशन के माध्यम से जाना चाहिए, जैसे: https://en.wikipedia.org/wiki/X86_calling_conctionions X86 के लिए, जो प्रत्येक चर के लिए विशिष्ट रजिस्टरों या स्टैक स्थानों को निर्दिष्ट करता है।

फिर जैसा कि दिखाया गया है कि <मान अनुकूलित किया गया> जीडीबी में क्या मतलब है? , -O0फिर सब कुछ ढेर में डाल देता है, जबकि -O3संभव के रूप में रजिस्टरों का उपयोग करने की कोशिश करता है।

हालाँकि, यदि फ़ंक्शन इनलाइन हो जाता है, तो उन्हें नियमित स्थानीय लोगों की तरह ही व्यवहार किया जाता है।

const

मेरा मानना ​​है कि इससे कोई फर्क नहीं पड़ता क्योंकि आप इसे टाइपकास्ट कर सकते हैं।

इसके विपरीत, यदि कंपाइलर यह निर्धारित करने में सक्षम है कि कुछ डेटा कभी नहीं लिखा गया है, तो यह सिद्धांत रूप में इसे जगह दे सकता है .rodata भले ही वह न हो।

TODO विश्लेषण।

संकेत

वे चर हैं (जिसमें पते शामिल हैं, जो संख्याएं हैं), इसलिए सभी शेष :-)

malloc

एक फ़ंक्शन है, और: इस सवाल का बहुत मतलब नहीं है malloc,malloc

int *i = malloc(sizeof(int));

*i एक चर है जिसमें एक पता होता है, इसलिए यह उपरोक्त मामले पर पड़ता है।

जैसे कि मॉलॉक आंतरिक रूप से कैसे काम करता है, जब आप इसे कहते हैं तो लिनक्स कर्नेल अपने आंतरिक डेटा संरचनाओं पर लिखने योग्य के रूप में कुछ पते चिह्नित करता है, और जब उन्हें प्रोग्राम द्वारा शुरू में छुआ जाता है, तो एक गलती होती है और कर्नेल पृष्ठ तालिकाओं को सक्षम करता है, जो एक्सेस की सुविधा देता है बिना सेगफुल के होता है: x86 पेजिंग कैसे करता है?

ध्यान दें कि यह मूल रूप से वही है जो execsyscall हुड के नीचे करता है जब आप एक निष्पादन योग्य चलाने की कोशिश करते हैं: यह उन पृष्ठों को चिह्नित करता है जो इसे लोड करना चाहते हैं, और वहां प्रोग्राम लिखते हैं, यह भी देखें: कर्नेल को एक निष्पादन योग्य बाइनरी फ़ाइल के तहत कैसे चल रहा है linux? सिवाय इसके कि execकुछ अतिरिक्त सीमाएँ हैं जहाँ पर लोड करना है (जैसे कि कोड स्थानांतरित नहीं है )।

सटीक के लिए इस्तेमाल किया syscall mallocहै mmapआधुनिक 2020 कार्यान्वयन में, और अतीत में brkइस्तेमाल किया गया था: क्या malloc () उपयोग brk () या mmap ()?

गतिशील पुस्तकालय

मूल रूप mmapसे स्मृति में एड करें: /unix/226524/what-system-call-is-used-to-load-lbooks-in-linux/462710#462710

एनवायरनमेंट वेरिएबल्स और mainएसargv

प्रारंभिक स्टैक के ऊपर: /unix/75939/where-is-the-environment-string-actual-stored TODO क्यों नहीं .data में?

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.