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


180

एक निष्पादन योग्य फ़ाइल के किस खंड (.BSS, .DATA, अन्य) में स्थिर चर संग्रहीत किए जाते हैं ताकि उनके पास नाम टक्कर न हो? उदाहरण के लिए:


foo.c:                         bar.c:
static int foo = 1;            static int foo = 10;
void fooTest() {               void barTest() {
  static int bar = 2;            static int bar = 20;
  foo++;                         foo++;
  bar++;                         bar++;
  printf("%d,%d", foo, bar);     printf("%d, %d", foo, bar);
}                              }

अगर मैं दोनों फाइलों को संकलित करता हूं और इसे एक मुख्य से जोड़ता हूं जो बार-बार fooTest () और बारटेस्ट कहता है, तो प्रिंटफ स्टेटमेंट स्वतंत्र रूप से बढ़ाता है। फू और बार चर के बाद से समझ में आता है अनुवाद इकाई के लिए स्थानीय हैं।

लेकिन भंडारण कहाँ आवंटित किया गया है?

स्पष्ट होने के लिए, धारणा यह है कि आपके पास एक टूलकिन है जो कि एलएलएफ प्रारूप में एक फ़ाइल का उत्पादन करेगा। इस प्रकार, मैं विश्वास है कि वहाँ कि है कुछ जगह उन स्थैतिक चर के लिए निष्पादन योग्य फ़ाइल में आरक्षित किया जाना।
चर्चा के उद्देश्यों के लिए, मान लें कि हम GCC टूलकिन का उपयोग करते हैं।


1
अधिकांश लोग आपको बता रहे हैं कि उन्हें आपके प्रश्न का उत्तर देने के बजाय .DATA अनुभाग में संग्रहीत किया जाना चाहिए: वास्तव में .DATA अनुभाग में और आप कहाँ मिल सकते हैं। मैं देखता हूं कि आपने पहले से ही एक उत्तर चिह्नित कर दिया है, इसलिए आप पहले से ही जानते हैं कि इसे कैसे खोजना है?
lukmac

क्यों प्रारंभिक और असंवैधानिक
mhk

1
रनटाइम के दौरान आपके ग्लोबल / स्टैटिक वेरिएबल्स को आवंटित स्टोरेज का उनके नाम रिज़ॉल्यूशन से कोई लेना-देना नहीं है, जो बिल्ड / लिंक टाइम के दौरान होता है। निष्पादन योग्य बनाया जाने के बाद - कोई और नाम नहीं हैं।
वाल्डो

2
यह प्रश्न निरर्थक है, झूठे आधार पर बनाया जा रहा है कि गैर-चिन्हित प्रतीकों का "नाम टक्कर" एक ऐसी चीज है जो मौजूद हो सकती है। तथ्य यह है कि कोई भी वैध सवाल नहीं है, यह समझा सकता है कि कुछ जवाब कितने गंभीर हैं। यह विश्वास करना मुश्किल है कि बहुत कम लोगों को यह मिला है।
अंडरस्कोर_ड

जवाबों:


131

जहां आपके स्टेटिक्स चलते हैं, वे इस बात पर निर्भर करते हैं कि क्या वे शून्य-आरंभीकृत हैंशून्य-इनिशियलाइज्ड स्टैटिक डेटा बीबीएस (ब्लॉक सिंबल बाय सिंबल) में जाता है , नॉन-जीरो इनिशियलाइज्ड डेटा डेटा में जाता है


50
"नॉन-0 इनिशियलाइज़्ड" से आपका शायद मतलब है "इनिशियलाइज़्ड, लेकिन 0 के अलावा किसी और चीज़ के साथ"। क्योंकि C / C ++ में "नॉन इनिशियलाइज़्ड" स्टैटिक डेटा जैसी कोई चीज़ नहीं है। सब कुछ डिफ़ॉल्ट रूप से शून्य-प्रारंभिक है।
AT

21
@ डोन नेफेल्ड: आपका जवाब सवाल का बिल्कुल भी जवाब नहीं देता। मुझे समझ नहीं आता कि इसे क्यों स्वीकार किया जाता है। क्योंकि 'फू' और 'बार' दोनों ही गैर-0 हैं। सवाल यह है कि .bs या
.data

मैंने उन कार्यान्वयनों का उपयोग किया है जहां स्थिर डेटा जो स्पष्ट रूप से शून्य-आरंभिक था .data, और स्थैतिक डेटा जिसमें कोई आरंभीकरण नहीं था .bss
एमएम

1
@MM मेरे मामले में कि क्या स्थिर सदस्य uninitialized है (कथित रूप से 0 से आरंभिक) या स्पष्ट रूप से 0 से आरंभिक है, दोनों ही मामलों में यह .bss अनुभाग में जोड़ा गया है।
cbinder

क्या यह जानकारी एक निश्चित निष्पादन योग्य फ़ाइल प्रकार के लिए विशिष्ट है? मैं मानता हूं, क्योंकि आपने निर्दिष्ट नहीं किया है कि यह कम से कम ELF और Windows PE निष्पादन योग्य फ़ाइलों पर लागू होता है, लेकिन अन्य प्रकारों के बारे में क्या?
जेरी जेरेमिया

116

जब किसी प्रोग्राम को मेमोरी में लोड किया जाता है, तो उसे विभिन्न सेगमेंट में व्यवस्थित किया जाता है। एक सेगमेंट DATA सेगमेंट है । डेटा खंड को आगे दो भागों में विभाजित किया गया है:

प्रारंभिक डेटा खंड: सभी वैश्विक, स्थिर और स्थिर डेटा यहां संग्रहीत हैं।
Uninitialized data सेगमेंट (BSS): इस खंड में सभी uninitialized डेटा को संग्रहीत किया जाता है।

इस अवधारणा को समझाने के लिए यहां एक चित्र दिया गया है:

यहां छवि विवरण दर्ज करें


यहाँ इन अवधारणाओं को समझाने के लिए बहुत अच्छी कड़ी है:

http://www.inf.udec.cl/~leo/teoX.pdf


ऊपर दिए गए उत्तर में कहा गया है कि 0 आरंभिक रूप से BSS में जाता है। क्या 0 इनिशियलाइज्ड का मतलब अनइंस्टालिअन्ड या 0 प्रति से है? अगर इसका मतलब 0 प्रति है तो मुझे लगता है कि आपको इसे अपने उत्तर में शामिल करना चाहिए।
विराज

लगातार डेटा को .data सेगमेंट में नहीं बल्कि टेक्स्ट सेक्शन के .const सेगमेंट में संग्रहीत किया जाता है।
user10678

इसके बजाय (" आरंभिक डेटा खंड : सभी वैश्विक, स्थैतिक और स्थिर डेटा यहां संग्रहीत हैं। अनधिकृत डेटा खंड (BSS) : सभी खंडों का डेटा इस खंड में संग्रहीत किया जाता है।"), मुझे लगता है कि इसे यह कहना चाहिए: (" आरंभिक डेटा सेगमेंट : सभी वैश्विक और स्थिर वैरिएबल जिन्हें गैर-शून्य मान पर आरंभीकृत किया गया था, और सभी स्थिर डेटा को यहां संग्रहीत किया जाता है। Uninitialized डेटा सेगमेंट (BSS) : सभी वैश्विक और स्थिर वैरिएबल जो या तो आरंभीकृत नहीं किए गए थे, या प्रारंभिक। शून्य पर, इस सेगमेंट में संग्रहीत हैं। ")।
गेब्रियल स्टेपल्स 21

भी ध्यान रखें कि जहां तक मैं यह समझ के रूप में, "प्रारंभ डेटा" initialized हो सकते हैं चर और स्थिरांक । एक माइक्रोकंट्रोलर (पूर्व: STM32) पर, प्रारंभिक चर को फ्लैश मेमोरी में डिफ़ॉल्ट रूप से संग्रहीत किया जाता है और स्टार्टअप पर रैम में कॉपी किया जाता है , और आरंभिक स्थिरांक में छोड़ दिया जाता है, और पाठ से पढ़ने के लिए अभिप्रेत है, केवल पाठ के साथ , जिसमें पाठ शामिल हैं कार्यक्रम ही, और केवल फ़्लैश
गेब्रियल स्टेपल्स 21

तो मैं इस आरेख से जो इकट्ठा कर रहा हूं वह यह है कि वैरिएबल जो वैश्विक या स्थिर हैं (चूंकि स्थिर वैरिएबल अवधि में वैश्विक चर की तरह काम करते हैं) न तो ढेर पर हैं और न ही स्टैक, बल्कि उन दोनों के अलावा मेमोरी पर आवंटित किए जाते हैं। क्या वह सही है? मुझे लगता है कि मैं स्मृति आवंटन का अधिक अध्ययन करने के लिए एक STM32 लिंकर स्क्रिप्ट पर फिर से नज़र डाल सकता हूं।
गैब्रियल स्टेपल्स

32

वास्तव में, एक टुपल (भंडारण, गुंजाइश, प्रकार, पता, मूल्य) है:

storage     :   where is it stored, for example data, stack, heap...
scope       :   who can see us, for example global, local...
type        :   what is our type, for example int, int*...
address     :   where are we located
value       :   what is our value

स्थानीय स्कोप का अर्थ हो सकता है कि स्थानीय या तो अनुवादक इकाई (स्रोत फ़ाइल), फ़ंक्शन या ब्लॉक को परिभाषित करें जहां यह परिभाषित किया गया है। चर को एक से अधिक कार्य के लिए दृश्यमान बनाने के लिए, यह निश्चित रूप से या तो DATA या BSS क्षेत्र में होना चाहिए (यह निर्भर करता है कि क्रमशः इसका इनिशियलाइज़ किया गया है या नहीं)। इसके बाद स्रोत फ़ाइल के भीतर सभी फ़ंक्शन (एस) या फ़ंक्शन (एस) के अनुसार स्कूप किया गया।


21

डेटा का संग्रहण स्थान कार्यान्वयन पर निर्भर होगा।

हालांकि, स्थैतिक का अर्थ "आंतरिक जुड़ाव" है। इस प्रकार, प्रतीक संकलन इकाई (foo.c, bar.c) के लिए आंतरिक है और उस संकलन इकाई के बाहर संदर्भित नहीं किया जा सकता है। तो, कोई नाम टकराव नहीं हो सकता।


नहीं। स्टैटिक कीवर्ल्ड के अर्थ ओवरलोडेड होते हैं: ऐसे में स्टेटिक स्टोरेज मोडिफायर होता है, लिंकेज मॉडिफायर नहीं।
ugasoft

4
ugasoft: फ़ंक्शन के बाहर के स्टैटिक्स लिंकेज मॉडिफ़ायर हैं, अंदर स्टोरेज मॉडिफ़ायर हैं, जहां से शुरू होने के लिए कोई टक्कर नहीं हो सकती है।
wnoise

12

"वैश्विक और स्थिर" क्षेत्र में :)

C ++ में कई मेमोरी क्षेत्र हैं:

  • ढेर
  • मुफ्त की दुकान
  • ढेर
  • वैश्विक और स्थिर
  • स्थिरांक

अपने प्रश्न के विस्तृत उत्तर के लिए यहां देखें :

निम्नलिखित एक C ++ प्रोग्राम के प्रमुख विशिष्ट मेमोरी क्षेत्रों को सारांशित करता है। ध्यान दें कि कुछ नाम (जैसे, "हीप") ड्राफ्ट [मानक] में दिखाई नहीं देते हैं।

     Memory Area     Characteristics and Object Lifetimes
     --------------  ------------------------------------------------

     Const Data      The const data area stores string literals and
                     other data whose values are known at compile
                     time.  No objects of class type can exist in
                     this area.  All data in this area is available
                     during the entire lifetime of the program.

                     Further, all of this data is read-only, and the
                     results of trying to modify it are undefined.
                     This is in part because even the underlying
                     storage format is subject to arbitrary
                     optimization by the implementation.  For
                     example, a particular compiler may store string
                     literals in overlapping objects if it wants to.


     Stack           The stack stores automatic variables. Typically
                     allocation is much faster than for dynamic
                     storage (heap or free store) because a memory
                     allocation involves only pointer increment
                     rather than more complex management.  Objects
                     are constructed immediately after memory is
                     allocated and destroyed immediately before
                     memory is deallocated, so there is no
                     opportunity for programmers to directly
                     manipulate allocated but uninitialized stack
                     space (barring willful tampering using explicit
                     dtors and placement new).


     Free Store      The free store is one of the two dynamic memory
                     areas, allocated/freed by new/delete.  Object
                     lifetime can be less than the time the storage
                     is allocated; that is, free store objects can
                     have memory allocated without being immediately
                     initialized, and can be destroyed without the
                     memory being immediately deallocated.  During
                     the period when the storage is allocated but
                     outside the object's lifetime, the storage may
                     be accessed and manipulated through a void* but
                     none of the proto-object's nonstatic members or
                     member functions may be accessed, have their
                     addresses taken, or be otherwise manipulated.


     Heap            The heap is the other dynamic memory area,
                     allocated/freed by malloc/free and their
                     variants.  Note that while the default global
                     new and delete might be implemented in terms of
                     malloc and free by a particular compiler, the
                     heap is not the same as free store and memory
                     allocated in one area cannot be safely
                     deallocated in the other. Memory allocated from
                     the heap can be used for objects of class type
                     by placement-new construction and explicit
                     destruction.  If so used, the notes about free
                     store object lifetime apply similarly here.


     Global/Static   Global or static variables and objects have
                     their storage allocated at program startup, but
                     may not be initialized until after the program
                     has begun executing.  For instance, a static
                     variable in a function is initialized only the
                     first time program execution passes through its
                     definition.  The order of initialization of
                     global variables across translation units is not
                     defined, and special care is needed to manage
                     dependencies between global objects (including
                     class statics).  As always, uninitialized proto-
                     objects' storage may be accessed and manipulated
                     through a void* but no nonstatic members or
                     member functions may be used or referenced
                     outside the object's actual lifetime.

12

मुझे विश्वास नहीं है कि कोई टकराव होगा। फ़ाइल स्तर (स्थिर कार्यों) पर स्थिर का उपयोग करना चर को वर्तमान संकलन इकाई (फ़ाइल) के रूप में स्थानीय के रूप में चिह्नित करता है। यह वर्तमान फ़ाइल के बाहर कभी दिखाई नहीं देता है, इसलिए कभी भी ऐसा नाम नहीं होना चाहिए जिसे बाहरी रूप से उपयोग किया जा सके।

अंदर स्थिर का उपयोग करनाकिसी फ़ंक्शन के अलग है - चर केवल फ़ंक्शन (चाहे स्थिर हो या नहीं) के लिए दृश्यमान है, यह सिर्फ उस फ़ंक्शन के लिए कॉल के पार इसका मूल्य संरक्षित है।

वास्तव में, स्थैतिक दो अलग-अलग चीजों पर निर्भर करता है कि वह कहाँ है। में दोनों मामलों हालांकि, चर दृश्यता इस तरह से कि आप आसानी से नाम स्थान संघर्ष जब जोड़ने रोका जा सकता है में सीमित है।

ऐसा कहने के बाद, मेरा मानना ​​है कि इसे DATAअनुभाग में संग्रहीत किया जाएगा , जिसमें ऐसे चर होते हैं जो शून्य के अलावा अन्य मानों के लिए आरंभिक होते हैं। यह, निश्चित रूप से, एक कार्यान्वयन विवरण, मानक द्वारा अनिवार्य कुछ नहीं है - यह केवल व्यवहार के बारे में परवाह करता है, न कि कैसे चीजों को कवर के तहत किया जाता है।


1
@ पैक्सडीब्लो: आपने दो प्रकार के स्थिर चर का उल्लेख किया है। उनमें से कौन सा यह लेख ( en.wikipedia.org/wiki/Data_segment ) संदर्भित करता है? डेटा खंड में वैश्विक चर भी होते हैं (जो स्थैतिक की प्रकृति के बिल्कुल विपरीत होते हैं)। So, how does a segment of memory (Data Segment) store variables that can be accessed from everywhere (global variables) and also those which have limited scope (file scope or function scope in case of static variables)?
लेज़र

@eSay, यह दृश्यता के साथ क्या करना है। एक खंड में संग्रहीत चीजें हो सकती हैं जो एक संकलन इकाई के लिए स्थानीय हैं, अन्य जो पूरी तरह से सुलभ हैं। एक उदाहरण: DATA सेगमेंट में एक ब्लॉक का योगदान करने वाले प्रत्येक कंप-यूनिट के बारे में सोचें। यह जानता है कि उस ब्लॉक में सब कुछ कहां है। यह ब्लॉक में उन चीजों के पते को भी प्रकाशित करता है, जो अन्य कॉम्प-यूनिट को एक्सेस करने की इच्छा रखता है। लिंकर उन पते को लिंक समय पर हल कर सकता है।
paxdiablo

11

इसे अपने साथ कैसे पाएं objdump -Sr

वास्तव में क्या चल रहा है यह समझने के लिए, आपको लिंकर स्थानांतरण को समझना चाहिए। यदि आपने कभी ऐसा नहीं छुआ है, तो पहले इस पोस्ट को पढ़ने पर विचार करें

चलो इसे देखने के लिए लिनक्स x86-64 ELF उदाहरण का विश्लेषण करें:

#include <stdio.h>

int f() {
    static int i = 1;
    i++;
    return i;
}

int main() {
    printf("%d\n", f());
    printf("%d\n", f());
    return 0;
}

संकलन:

gcc -ggdb -c main.c

इसके साथ कोड घटाएँ:

objdump -Sr main.o
  • -S कोड को मूल स्रोत के साथ विघटित कर देता है
  • -r स्थानांतरण जानकारी दिखाता है

विघटन के अंदर fहम देखते हैं:

 static int i = 1;
 i++;
4:  8b 05 00 00 00 00       mov    0x0(%rip),%eax        # a <f+0xa>
        6: R_X86_64_PC32    .data-0x4

और .data-0x4कहता है कि यह .dataखंड के पहले बाइट में जाएगा ।

-0x4वहाँ है, क्योंकि हम को संबोधित कर प्रयोग कर रहे हैं आरआईपी रिश्तेदार है, इस प्रकार %ripशिक्षा में और R_X86_64_PC32

इसकी आवश्यकता है क्योंकि आरआईपी निम्नलिखित निर्देश को इंगित करता है , जो 4 बाइट्स शुरू 00 00 00 00करता है जिसके बाद क्या स्थानांतरित हो जाएगा। मैंने इसे और अधिक विस्तार से समझाया है: https://stackoverflow.com/a/30515926/895245

फिर, यदि हम स्रोत को संशोधित i = 1करते हैं और उसी विश्लेषण को करते हैं, तो हम यह निष्कर्ष निकालते हैं:

  • static int i = 0 चलता रहता है .bss
  • static int i = 1 चलता रहता है .data


6

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


5

एक संकलन इकाई में घोषित किया गया डेटा .BSS या उस फ़ाइलों के .Data में जाएगा। BSS में प्रारंभिक डेटा, डेटा में अनइंस्टॉल किया गया।

स्थिर और वैश्विक डेटा के बीच का अंतर फ़ाइल में प्रतीक सूचना के समावेश में आता है। संकलक प्रतीक सूचना को शामिल करते हैं, लेकिन केवल वैश्विक जानकारी को ऐसे ही चिह्नित करते हैं।

लिंकर इस जानकारी का सम्मान करता है। स्थैतिक चर के लिए प्रतीक सूचना को या तो त्याग दिया जाता है या मंगवा लिया जाता है ताकि स्थैतिक चर को अभी भी किसी तरह से (डिबग या प्रतीक विकल्पों के साथ) संदर्भित किया जा सके। न तो मामले में संकलन इकाइयां प्रभावित हो सकती हैं क्योंकि लिंकर पहले स्थानीय संदर्भों को हल करता है।


3

मैंने इसे objdump और gdb के साथ आज़माया, यहाँ परिणाम है जो मुझे मिलता है:

(gdb) disas fooTest
Dump of assembler code for function fooTest:
   0x000000000040052d <+0>: push   %rbp
   0x000000000040052e <+1>: mov    %rsp,%rbp
   0x0000000000400531 <+4>: mov    0x200b09(%rip),%eax        # 0x601040 <foo>
   0x0000000000400537 <+10>:    add    $0x1,%eax
   0x000000000040053a <+13>:    mov    %eax,0x200b00(%rip)        # 0x601040 <foo>
   0x0000000000400540 <+19>:    mov    0x200afe(%rip),%eax        # 0x601044 <bar.2180>
   0x0000000000400546 <+25>:    add    $0x1,%eax
   0x0000000000400549 <+28>:    mov    %eax,0x200af5(%rip)        # 0x601044 <bar.2180>
   0x000000000040054f <+34>:    mov    0x200aef(%rip),%edx        # 0x601044 <bar.2180>
   0x0000000000400555 <+40>:    mov    0x200ae5(%rip),%eax        # 0x601040 <foo>
   0x000000000040055b <+46>:    mov    %eax,%esi
   0x000000000040055d <+48>:    mov    $0x400654,%edi
   0x0000000000400562 <+53>:    mov    $0x0,%eax
   0x0000000000400567 <+58>:    callq  0x400410 <printf@plt>
   0x000000000040056c <+63>:    pop    %rbp
   0x000000000040056d <+64>:    retq   
End of assembler dump.

(gdb) disas barTest
Dump of assembler code for function barTest:
   0x000000000040056e <+0>: push   %rbp
   0x000000000040056f <+1>: mov    %rsp,%rbp
   0x0000000000400572 <+4>: mov    0x200ad0(%rip),%eax        # 0x601048 <foo>
   0x0000000000400578 <+10>:    add    $0x1,%eax
   0x000000000040057b <+13>:    mov    %eax,0x200ac7(%rip)        # 0x601048 <foo>
   0x0000000000400581 <+19>:    mov    0x200ac5(%rip),%eax        # 0x60104c <bar.2180>
   0x0000000000400587 <+25>:    add    $0x1,%eax
   0x000000000040058a <+28>:    mov    %eax,0x200abc(%rip)        # 0x60104c <bar.2180>
   0x0000000000400590 <+34>:    mov    0x200ab6(%rip),%edx        # 0x60104c <bar.2180>
   0x0000000000400596 <+40>:    mov    0x200aac(%rip),%eax        # 0x601048 <foo>
   0x000000000040059c <+46>:    mov    %eax,%esi
   0x000000000040059e <+48>:    mov    $0x40065c,%edi
   0x00000000004005a3 <+53>:    mov    $0x0,%eax
   0x00000000004005a8 <+58>:    callq  0x400410 <printf@plt>
   0x00000000004005ad <+63>:    pop    %rbp
   0x00000000004005ae <+64>:    retq   
End of assembler dump.

यहाँ objdump परिणाम है

Disassembly of section .data:

0000000000601030 <__data_start>:
    ...

0000000000601038 <__dso_handle>:
    ...

0000000000601040 <foo>:
  601040:   01 00                   add    %eax,(%rax)
    ...

0000000000601044 <bar.2180>:
  601044:   02 00                   add    (%rax),%al
    ...

0000000000601048 <foo>:
  601048:   0a 00                   or     (%rax),%al
    ...

000000000060104c <bar.2180>:
  60104c:   14 00                   adc    $0x0,%al

तो, यह कहना है कि आपके चार चर डेटा सेक्शन इवेंट में एक ही नाम पर स्थित हैं, लेकिन अलग-अलग ऑफसेट के साथ।


से बहुत अधिक है। यहां तक ​​कि मौजूदा जवाब भी पूरे नहीं हैं। बस कुछ और का उल्लेख करने के लिए: धागा स्थानीय।
एड्रियानो रेपेती

2

जैसा कि पहले उल्लेख किया गया है डेटा सेगमेंट या कोड सेगमेंट में संग्रहीत स्थिर चर।
आप यह सुनिश्चित कर सकते हैं कि यह ढेर या ढेर पर आवंटित नहीं किया जाएगा।
टक्कर के लिए कोई जोखिम नहीं है क्योंकि staticकीवर्ड चर के दायरे को फ़ाइल या फ़ंक्शन के रूप में परिभाषित करता है, टक्कर के मामले में आपको चेतावनी देने के लिए एक कंपाइलर / लिंकर है।
एक अच्छा उदाहरण है


2

वैसे यह सवाल थोड़ा बहुत पुराना है, लेकिन चूंकि कोई भी कोई उपयोगी जानकारी नहीं बताता है: 'mohit12379' द्वारा पोस्ट की जाँच करें कि प्रतीक तालिका में एक ही नाम के साथ स्थिर चर के स्टोर की व्याख्या: http://www.geekinterview.com/question_destails/ 24745


1

उत्तर बहुत अच्छी तरह से संकलक पर निर्भर हो सकता है, इसलिए आप शायद अपने प्रश्न को संपादित करना चाहते हैं (मेरा मतलब है, यहां तक ​​कि खंडों की धारणा आईएसओ सी या आईएसओ सी ++ द्वारा अनिवार्य नहीं है)। उदाहरण के लिए, विंडोज़ पर एक निष्पादन योग्य प्रतीक नाम नहीं रखता है। एक 'फू' की भरपाई 0x100 होगी, दूसरी शायद 0x2B0, और दोनों अनुवाद इकाइयों के कोड को "उनके" फू के लिए ऑफ़सेट जानते हुए संकलित किया जाएगा।


0

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


-1

आप पहले से ही जानते हैं कि यह bss में स्टोर होता है (सिंबल द्वारा ब्लॉक स्टार्ट) जिसे अनइंस्टाल्यूटेड डेटा सेगमेंट या इनिशियलाइज़्ड डेटा सेगमेंट के रूप में भी जाना जाता है।

एक सरल उदाहरण लेते हैं

void main(void)
{
static int i;
}

उपरोक्त स्टैटिक वैरिएबल को इनिशियलाइज़ नहीं किया गया है, इसलिए यह uninitialized डेटा सेगमेंट (bss) में जाता है।

void main(void)
{
static int i=10;
}

और निश्चित रूप से यह 10 से इनिशियलाइज़्ड है इसलिए यह इनिशियलाइज़्ड डेटा सेगमेंट में जाता है।

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