2015-04-16 14 views
8

मेरे पास यह कोड है और मुझे स्मृति आवंटन के बारे में आश्चर्य है।आवंटित स्थैतिक वस्तु के गैर स्थैतिक सदस्य कहां हैं?

void f(){ 
     static A a; 
     //Other things... 
    } 

    class A { 
     public: 
      A(); 
     private: 
      AnotherObjectType anotherObject; 
    }; 

anotherObject आवंटित किया जाएगा? static कोड सेगमेंट में या कहीं और? क्या ओवरराइट होने के लिए anotherObject का जोखिम है? (f कई बार बुलाया जाएगा)।

उत्तर

5

सभी गैर-ढेर ऑब्जेक्ट स्थिर खंड में होंगे, स्थिर स्थिर (एफ) के उदाहरण के अंदर।

ओवरराइटिंग के बारे में, यह पुराने सी/सी ++ में हो सकता है यदि आपने बहु-थ्रेडेड कोड में विभिन्न सिंगलटन मुहावरे का उपयोग किया है। लेकिन उदा। नए जीसीसी संस्करण स्थैतिक वस्तुओं के स्वत: थ्रेड-सुरक्षित प्रारंभिकरण के लिए नई मानक आवश्यकताओं का उपयोग करते हैं। उदाहरण देखें Is local static variable initialization thread-safe in C++11?

+0

एकमात्र उत्तर जो अब तक पोस्ट और पूर्व सी ++ 11 – senfen

+2

में स्थिर चर के व्यवहार में अंतर बताता है, ठीक है, गैर-* हीप * वास्तव में गैर- * गतिशील * का मतलब है। यदि गति आवंटक का उपयोग किया जाता है तो गतिशील रूप से आवंटित ऑब्जेक्ट स्थिर खंड में भी हो सकते हैं। "हीप" एक कार्यान्वयन विवरण है जो सबसे ज्यादा उपयोग किया जाता है। –

+0

सावधान रहें कि मुझे नहीं लगता कि विज़ुअल सी ++ वीएस2015 से पहले थ्रेड सुरक्षित स्थैतिक प्रारंभिकरण (जादू सांख्यिकी) लागू करता है। – sjdowling

0

चर a एक स्थिर चर रहा है और केवल एक बार घोषित किया जाता है, इसका मतलब है कि A a; बयान केवल एक बार निष्पादित कर रहा है। चर का दायरा f गुंजाइश से ऊपर है। क्षेत्र anotherObject ए ऑब्जेक्ट के आवंटन के भीतर है।

गिनती के साथ उदाहरण देखें:

#include <iostream> 
using namespace std; 
class AnotherObjectType {}; 

class A { 
public: 
    A(){count = 0;}; 
    int count; 
private: 
    AnotherObjectType anotherObject; 
}; 

A f(){ 
    static A a; 
    a.count++; 
    //Other things... 
    return a; 
} 

int main() { 
    // your code goes here 
    A a; 
    for (int i = 0; i < 3; i++) { 
     a = f(); 
     std::cout << "Count: " << a.count << std::endl; 
    } 
    return 0; 
} 

कार्य उदाहरण: http://ideone.com/USqeEZ

भी देखें: http://www.learncpp.com/cpp-tutorial/811-static-member-variables/

0
void f(){ 
    /// this created in static segment - that's obviously for you 
    static A a; 
    //Other things... 
} 

class A { 
    public: 
     A(); 
    private: 
     /// anotherObject is not pointer but explicit part of A, 
     /// so it won't be created in heap or anywhere else, 
     /// but in the same memory segment as an instance of A. 
     AnotherObjectType anotherObject; 
}; 

तो, anotherObject ओवरराइट नहीं किया जाएगा क्योंकि static A a एक का एक उदाहरण बनाने स्थैतिक सेगमेंट में और किसी अन्य उदाहरण को अन्य सेगमेंट में क्रेट किया जाएगा, इस पर निर्भर करता है कि आप किस सेगमेंट को बनाएंगे।

+0

टिप्पणियों में स्पष्टीकरण के बिना शून्य क्यों? क्या गलत है? –

+1

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

+0

स्पष्टीकरण के लिए बहुत बहुत धन्यवाद। और मुझे मेरी बुरी अंग्रेजी के लिए क्षमा करें।) –

0

हालांकि दोनों को स्थिर कहा जाता है, एक स्थैतिक सदस्य स्थिर स्थानीय चर से अलग होता है।

कक्षा में एक स्थिर सदस्य साझा किया जाता है। इस वर्ग का हर उदाहरण एक ही सदस्य को संदर्भित करता है।

एक स्थैतिक स्थानीय चर एक बार शुरू किया जाता है, और फ़ंक्शन लौटने पर नष्ट नहीं होता है।

आपके कोड में, गैर-स्थैतिक सदस्यों को उदाहरण a में संग्रहीत किया जाता है, और a फ़ंक्शन रिटर्न से परे बनी रहती है।

1

मेमोरी या तो स्थिर रूप से या गतिशील रूप से आवंटित किया गया है। गतिशील आवंटन वह होता है जो आपको रनटाइम पर स्मृति आवंटित करते समय मिलता है, उदाहरण के लिए new और malloc। स्टेटिक आवंटन "बाकी" है। कक्षा सदस्य चर के लिए मेमोरी क्लास इंस्टेंस के साथ आवंटित की जाती है, इसलिए यदि यह स्थिर रूप से आवंटित किया गया है, तो सदस्य स्मृति के उसी हिस्से में समाप्त होते हैं, और यदि गतिशील रूप से आवंटित किया जाता है, तो सदस्य गतिशील स्मृति रहते हैं। यह पॉइंटर सदस्य चर के लिए भी सच है, लेकिन वास्तविक स्मृति जो इसे इंगित करती है वह या तो गतिशील रूप से (new और malloc) या स्थाई रूप से आवंटित हो सकती है।

int i = 0; 
int* pi = &i;  // pi points at statically allocated memory 
pi = new int(0); // pi points at dynamically allocated memory 

इसलिए, यदि आप इसके लिए एक स्थिर वर्ग उदाहरण, स्मृति और उसके सदस्यों आमतौर पर कोड खंड में आवंटित है, लेकिन यह एक कार्यान्वयन विस्तार है।

यदि सदस्य एक सूचक है, जो गतिशील रूप से आवंटित स्मृति पर इंगित करता है, तो वह स्मृति होगी जहां प्रयुक्त आवंटक का निर्णय लेता है। "ढेर" गतिशील रूप से आवंटित स्मृति का सबसे आम कार्यान्वयन विवरण है, जिसे आप सामान्यतःnew और malloc का उपयोग करते समय प्राप्त करते हैं, लेकिन एक कस्टम आवंटक का उपयोग किया जा सकता है जो कोड सेगमेंट में कहीं और स्मृति को नियंत्रित करता है।

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