सरणी, ढेर और स्टैक और मूल्य प्रकार


134
int[] myIntegers;
myIntegers = new int[100];

उपरोक्त कोड में, नया int [100] ढेर पर सरणी उत्पन्न कर रहा है? मैंने C # के माध्यम से CLR पर जो पढ़ा है, उसका उत्तर हां है। लेकिन जो मैं नहीं समझ सकता, वह वही है जो वास्तविक इंट के सरणी के अंदर होता है। जैसा कि वे मूल्य प्रकार हैं, मुझे लगता है कि उन्हें बॉक्सिंग करना होगा, जैसा कि मैं कर सकता हूं, उदाहरण के लिए, प्रोग्राम के अन्य हिस्सों में myIntegers पास करें और यह ढेर को अव्यवस्थित कर देगा यदि वे हर समय उस पर छोड़ दिए गए थे। । या मैं गलत हूँ? मुझे लगता है कि वे सिर्फ बॉक्सिंग करेंगे और ढेर पर रहेंगे जब तक सरणी मौजूद रहेगी।

जवाबों:


289

आपका सरणी ढेर पर आवंटित किया गया है, और इन्ट्स बॉक्सिंग नहीं हैं।

आपके भ्रम का स्रोत होने की संभावना है क्योंकि लोगों ने कहा है कि संदर्भ प्रकार ढेर पर आवंटित किए गए हैं, और मूल्य प्रकार स्टैक पर आवंटित किए गए हैं। यह पूरी तरह से सटीक प्रतिनिधित्व नहीं है।

सभी स्थानीय चर और पैरामीटर स्टैक पर आवंटित किए जाते हैं। इसमें मूल्य प्रकार और संदर्भ प्रकार दोनों शामिल हैं। दोनों के बीच अंतर केवल वही है जो चर में संग्रहीत है। मूल्य के प्रकार के लिए, आश्चर्यजनक रूप से, प्रकार का मूल्य सीधे चर में संग्रहीत किया जाता है, और एक संदर्भ प्रकार के लिए, प्रकार का मूल्य ढेर पर संग्रहीत किया जाता है, और इस मान का एक संदर्भ चर में संग्रहीत होता है।

वही खेतों के लिए रखती है। जब किसी कुल प्रकार ( classया a) के उदाहरण के लिए मेमोरी आवंटित की जाती हैstruct ) के , तो इसके प्रत्येक इंस्टेंस फ़ील्ड के लिए भंडारण शामिल होना चाहिए। संदर्भ-प्रकार के क्षेत्रों के लिए, यह संग्रहण केवल मान का संदर्भ रखता है, जिसे बाद में हीप पर आबंटित किया जाएगा। मूल्य-प्रकार के क्षेत्रों के लिए, यह संग्रहण वास्तविक मूल्य रखता है।

तो, निम्न प्रकार दिए गए:

class RefType{
    public int    I;
    public string S;
    public long   L;
}

struct ValType{
    public int    I;
    public string S;
    public long   L;
}

इन प्रकारों में से प्रत्येक के मान के लिए 16 बाइट्स मेमोरी (32-बिट शब्द आकार मानकर) की आवश्यकता होगी। Iप्रत्येक मामले में फ़ील्ड अपने मूल्य को संग्रहीत करने के लिए 4 बाइट्स लेता है, फ़ील्ड Sअपने संदर्भ को संग्रहीत करने के लिए 4 बाइट्स लेता है, और फ़ील्ड Lअपने मूल्य को संग्रहीत करने के लिए 8 बाइट्स लेता है। तो दोनों के मूल्य के लिए स्मृति RefTypeऔर ValTypeइस तरह दिखता है:

 0 ┌───────────────────┐
   │ मैं │
 4 ├───────────────────┤
   │ एस │
 8 ├───────────────────┤
   │ L │
   │ │
16 └───────────────────┘

अब अगर आपके पास एक फ़ंक्शन में तीन स्थानीय चर हैं, प्रकार RefTypeके ValType, और int[], जैसे:

RefType refType;
ValType valType;
int[]   intArray;

तब आपका स्टैक इस तरह दिख सकता है:

 0 ┌───────────────────┐
   T RefType │
 4 ├───────────────────┤
   │ वेल्टाइप │
   │ │
   │ │
   │ │
20 ├───────────────────┤
   Ray इंटेरियर ray
24 └───────────────────┘

यदि आप इन स्थानीय चर को मान असाइन करते हैं, जैसे:

refType = new RefType();
refType.I = 100;
refType.S = "refType.S";
refType.L = 0x0123456789ABCDEF;

valType = new ValType();
valType.I = 200;
valType.S = "valType.S";
valType.L = 0x0011223344556677;

intArray = new int[4];
intArray[0] = 300;
intArray[1] = 301;
intArray[2] = 302;
intArray[3] = 303;

तब आपका स्टैक कुछ इस तरह दिख सकता है:

 0 ┌───────────────────┐
   │ 0x4A963B68 │ - `refType` का ढेर पता
 4 ├───────────────────┤
   │ 200 │ - `valType.I` का मान
   │ 0x4A984C10 9 - `valType.S` का ढेर पता
   │ 0x44556677 │ - कम 32-बिट `valType.L`
   │ 0x00112233 12 - `valType.L` के 32-बिट्स
20 ├───────────────────┤
   │ 0x4AA4C288 4 - `intArray` का ढेर पता
24 └───────────────────┘

पते पर मेमोरी 0x4A963B68(मान refType) कुछ इस तरह होगी:

 0 ┌───────────────────┐
   │ 100 │ - `refType.I` का मान
 4 ├───────────────────┤
   │ 0x4A984D88 9 - `refType.S` का ढेर पता
 8 ├───────────────────┤
   │ 0x89ABCDEF AB - कम 32-बिट `refType.L`
   │ 0x01234567 │ - उच्च 32-बिट `refType.L`
16 └───────────────────┘

पते पर मेमोरी 0x4AA4C288(मान intArray) कुछ इस तरह होगी:

 0 ┌───────────────────┐
   Length 4 │ - सरणी की लंबाई
 4 ├───────────────────┤
   │ 300 │ - `इंट्रेयर [0]`
 8 ├───────────────────┤
   │ 301 │ - `इंट्रेयर [1]`
12 ├───────────────────┤
   │ 302 │ - `इंट्रेयर [2]`
16 ├───────────────────┤
   │ 303 │ - `इंट्रेयर [3]`
20 └───────────────────┘

अब, यदि आप intArrayकिसी अन्य फ़ंक्शन में गए हैं, तो स्टैक पर दिया गया मान 0x4AA4C288ऐरे का पता होगा , एरे की प्रति नहीं


52
मैं ध्यान देता हूं कि स्टैक पर सभी स्थानीय चर संग्रहित हैं, यह कथन गलत है। स्थानीय चर जो किसी अनाम फ़ंक्शन के बाहरी चर हैं, ढेर पर संग्रहीत होते हैं। इटरेटर ब्लॉकों के स्थानीय चर ढेर पर संग्रहीत किए जाते हैं। Async ब्लॉक के स्थानीय चर ढेर पर संग्रहीत किए जाते हैं। स्थानीय चर जो अपंजीकृत होते हैं, वे न तो स्टैक और न ही ढेर पर संग्रहीत होते हैं। स्थानीय चर जिन्हें एलेड किया जाता है, न तो स्टैक और न ही ढेर पर संग्रहीत होते हैं।
एरिक लिपर्ट

5
LOL, हमेशा नाइट-पिकर, मिस्टर लिपर्ट। :) मुझे लगता है कि आपके बाद के दो मामलों को छोड़कर, तथाकथित "स्थानीय लोगों" को संकलन समय पर स्थानीय होने के लिए कहा जाता है। कार्यान्वयन उन्हें कक्षा के सदस्यों की स्थिति तक बढ़ा देता है, जो एकमात्र कारण है जो उन्हें ढेर पर संग्रहीत किया जाता है। तो यह केवल एक कार्यान्वयन विवरण (स्नीकर) है। बेशक, रजिस्टर स्टोरेज एक और भी निचले स्तर का कार्यान्वयन विवरण है, और elision की गिनती नहीं है।
पी डैडी

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

16
जाहिरा तौर पर आपके पास एक अलग विचार है कि मेरे द्वारा किए गए "स्थानीय चर" होने का क्या मतलब है। आपको लगता है कि एक "स्थानीय चर" इसके कार्यान्वयन विवरण की विशेषता है । यह विश्वास C # विनिर्देश में मेरे द्वारा ज्ञात किसी भी चीज़ के लिए उचित नहीं है। एक स्थानीय चर वास्तव में एक चर एक ब्लॉक जिसका अंदर घोषित है नाम है दायरे में केवल ब्लॉक से संबंधित घोषणा अंतरिक्ष में। मैं आपको विश्वास दिलाता हूं कि स्थानीय चर जो कार्यान्वयन विस्तार के रूप में, क्लोजर क्लास के क्षेत्रों में फहराए जाते हैं, अभी भी C # के नियमों के अनुसार स्थानीय चर हैं
एरिक लिपर्ट

15
यह कहा, निश्चित रूप से आपका जवाब आम तौर पर उत्कृष्ट है; यह मान कि चर से वैचारिक रूप से भिन्न हैं वह एक है जिसे मौलिक रूप से जितनी बार और जितनी संभव हो उतनी जोर से बनाया जाना चाहिए। और फिर भी एक महान कई लोग उनके बारे में अजीब मिथकों को मानते हैं! अच्छी लड़ाई लड़ने के लिए आप पर इतना अच्छा।
एरिक लिपर्ट

23

हाँ सरणी ढेर पर स्थित होगी।

सरणी के अंदर की इन्टस को बॉक्सिंग नहीं किया जाएगा। सिर्फ इसलिए कि ढेर पर एक मूल्य प्रकार मौजूद है, जरूरी नहीं कि इसका मतलब यह बॉक्सिंग होगा। बॉक्सिंग केवल तब होगी जब कोई मान प्रकार, जैसे int, प्रकार ऑब्जेक्ट के संदर्भ में असाइन किया गया है।

उदाहरण के लिए

बॉक्स नहीं है:

int i = 42;
myIntegers[0] = 42;

बक्से:

object i = 42;
object[] arr = new object[10];  // no boxing here 
arr[0] = 42;

आप इस विषय पर एरिक की पोस्ट को देखना चाहते हैं:


1
लेकिन मुझे नहीं मिला। क्या स्टैक पर मूल्य प्रकार आवंटित नहीं किए जाने चाहिए? या मान और संदर्भ प्रकार दोनों को ढेर या स्टैक पर आवंटित किया जा सकता है और यह सिर्फ इतना है कि वे आमतौर पर एक ही स्थान या अन्य में संग्रहीत होते हैं?
भगोड़ा एलिसियम ११'०

4
@ जॉर्ज, कोई संदर्भ प्रकार के रैपर / कंटेनर के साथ एक मूल्य प्रकार स्टैक पर रहेगा। हालांकि एक बार इसे एक संदर्भ प्रकार के कंटेनर के भीतर उपयोग किया जाता है, यह ढेर में रहेगा। एक सरणी एक संदर्भ प्रकार है और इसलिए इंट के लिए मेमोरी ढेर में होनी चाहिए।
जारेडपर

2
@ जॉर्ज: संदर्भ प्रकार केवल ढेर में रहते हैं, स्टैक पर कभी नहीं। कंट्राइवाइज, एक रेफरेंस टाइप के ऑब्जेक्ट में पॉइंटर लोकेशन को पॉइंटर स्टोर करने के लिए (वेरिफायबल कोड में) यह असंभव है।
एंटोन टायखी

1
मुझे लगता है कि आपको गिरफ्तार करने के लिए मुझे नियुक्त करना था [0]। निरंतर असाइनमेंट अभी भी "42" की मुक्केबाजी का कारण बनेगा, लेकिन आपने मुझे बनाया है, इसलिए आप इसका उपयोग भी कर सकते हैं
;;

@AntonTykhyy: ऐसा कोई नियम नहीं है जिसके बारे में मैं कहूं कि CLR विश्लेषण से बच नहीं सकता। यदि यह पता लगाता है कि किसी ऑब्जेक्ट को उस फ़ंक्शन के जीवनकाल के अतीत से संदर्भित नहीं किया जाएगा जिसने इसे बनाया है, तो यह पूरी तरह से वैध है - और यहां तक ​​कि बेहतर - स्टैक पर ऑब्जेक्ट का निर्माण करने के लिए, चाहे वह मूल्य प्रकार हो या नहीं। "मान प्रकार" और "संदर्भ प्रकार" मूल रूप से वर्णन करते हैं कि चर द्वारा ली गई मेमोरी में क्या वस्तु है, जहां कोई कठोर और तेज नियम नहीं है।
cHao

21

यह समझने के लिए कि यहाँ क्या हो रहा है, कुछ तथ्य हैं:

  • ऑब्जेक्ट हमेशा ढेर पर आवंटित किए जाते हैं।
  • ढेर में केवल वस्तुएँ होती हैं।
  • मूल्य प्रकार या तो ढेर पर आवंटित किए जाते हैं, या ढेर पर किसी वस्तु का हिस्सा।
  • एक सरणी एक वस्तु है।
  • एक सरणी में केवल मान प्रकार हो सकते हैं।
  • एक वस्तु संदर्भ एक मूल्य प्रकार है।

इसलिए, यदि आपके पास पूर्णांकों की एक सरणी है, तो सरणी को ढेर पर आबंटित किया जाता है और पूर्णांक जिसमें यह समाहित है, ढेर पर सरणी ऑब्जेक्ट का हिस्सा है। पूर्णांक ढेर पर सरणी ऑब्जेक्ट के अंदर रहते हैं, अलग-अलग वस्तुओं के रूप में नहीं, इसलिए वे बॉक्सिंग नहीं हैं।

यदि आपके पास स्ट्रिंग का एक सरणी है, तो यह वास्तव में स्ट्रिंग संदर्भों की एक सरणी है। जैसा कि संदर्भ मूल्य प्रकार हैं वे ढेर पर सरणी ऑब्जेक्ट का हिस्सा होंगे। यदि आप एक स्ट्रिंग ऑब्जेक्ट को सरणी में रखते हैं, तो आप वास्तव में स्ट्रिंग ऑब्जेक्ट को सरणी में डालते हैं, और स्ट्रिंग हीप पर एक अलग ऑब्जेक्ट है।


हां, संदर्भ बिल्कुल मूल्य प्रकारों की तरह व्यवहार करते हैं लेकिन मैंने देखा कि उन्हें आमतौर पर उस तरह से नहीं कहा जाता है, या मूल्य प्रकारों में शामिल किया जाता है। उदाहरण के लिए देखें (लेकिन इस तरह के बहुत कुछ हैं) msdn.microsoft.com/en-us/library/s1ax56ch.aspx
हेंक

\ सब एक साथ फिट बैठता है। :)
गुफ़ा

मुझे 5 वें बिंदु पर संदेह है, "एक सरणी में केवल मूल्य प्रकार हो सकते हैं।" स्ट्रिंग सरणी के बारे में क्या? string [] स्ट्रिंग्स = new string [4];
सुनील पुरुषोत्तम

9

मुझे लगता है कि आपके प्रश्न के मूल में संदर्भ और मूल्य प्रकारों के बारे में गलतफहमी है। यह संभवत: हर .NET है और जावा डेवलपर के साथ संघर्ष किया है।

एक सरणी सिर्फ मूल्यों की एक सूची है। यदि यह एक संदर्भ प्रकार की एक सरणी है (कहते हैं string[]) तो सरणी stringढेर पर विभिन्न वस्तुओं के संदर्भों की एक सूची है , क्योंकि एक संदर्भ प्रकार का एक मूल्य है। आंतरिक रूप से, इन संदर्भों को स्मृति में एक पते पर संकेत के रूप में लागू किया जाता है। यदि आप इसकी कल्पना करना चाहते हैं, तो इस तरह की एक सरणी स्मृति में इस तरह दिखेगी (ढेर पर):

[ 00000000, 00000000, 00000000, F8AB56AA ]

यह एक सरणी stringहै जिसमें stringढेर पर वस्तुओं के 4 संदर्भ हैं (यहां संख्या हेक्साडेसिमल हैं)। वर्तमान में, केवल अंतिम stringवास्तव में किसी भी चीज की ओर इशारा करता है (मेमोरी को सभी शून्य के आवंटित होने पर शुरू किया जाता है), यह सरणी मूल रूप से C # में इस कोड का परिणाम होगा:

string[] strings = new string[4];
strings[3] = "something"; // the string was allocated at 0xF8AB56AA by the CLR

उपरोक्त सरणी 32 बिट प्रोग्राम में होगी। 64 बिट प्रोग्राम में, संदर्भ दोगुना बड़ा F8AB56AAहोगा ( होगा)00000000F8AB56AA )।

आप मूल्य प्रकार की एक सरणी है (एक का कहना है int[]) तो सरणी, पूर्णांकों की एक सूची है के रूप में मूल्य एक मान प्रकार की है मूल्य ही (इसलिए नाम)। इस तरह के एक सरणी का दृश्य यह होगा:

[ 00000000, 45FF32BB, 00000000, 00000000 ]

यह 4 पूर्णांक का एक सरणी है, जहां केवल दूसरे इंट को एक मान (1174352571 को, जो कि हेक्साडेसिमल संख्या का दशमलव प्रतिनिधित्व है) सौंपा गया है और शेष पूर्णांक 0 होंगे (जैसे मैंने कहा, स्मृति शून्य से आरंभीकृत है) और 00000000 हेक्साडेसिमल में दशमलव में 0 है)। इस सरणी को बनाने वाला कोड होगा:

 int[] integers = new int[4];
 integers[1] = 1174352571; // integers[1] = 0x45FF32BB would be valid too

इस int[]सरणी को भी ढेर पर संग्रहीत किया जाएगा।

एक अन्य उदाहरण के रूप में, एक short[4]सरणी की स्मृति इस तरह दिखाई देगी:

[ 0000, 0000, 0000, 0000 ]

मान के रूप में shortएक 2 बाइट संख्या है।

जहां एक मान प्रकार संग्रहीत किया जाता है, केवल एक कार्यान्वयन विवरण है क्योंकि एरिक लिपर्ट यहां बहुत अच्छी तरह से बताते हैं , मूल्य और संदर्भ प्रकार (जो व्यवहार में अंतर है) के बीच अंतर के लिए अंतर्निहित नहीं है।

जब आप किसी विधि को पास करते हैं (जैसे कि एक संदर्भ प्रकार या एक मूल्य प्रकार) तो उस प्रकार के मूल्य की एक प्रतिलिपि वास्तव में विधि को पारित कर दी जाती है। एक संदर्भ प्रकार के मामले में, मान एक संदर्भ है (इसे मेमोरी के एक टुकड़े के लिए एक संकेतक के रूप में सोचें, हालांकि यह एक कार्यान्वयन विस्तार भी है) और मूल्य प्रकार के मामले में, मूल्य ही चीज है।

// Calling this method creates a copy of the *reference* to the string
// and a copy of the int itself, so copies of the *values*
void SomeMethod(string s, int i){}

यदि आप किसी मान प्रकार को संदर्भ प्रकार में परिवर्तित करते हैं तो ही बॉक्सिंग होती है । यह कोड बॉक्स:

object o = 5;

मेरा मानना ​​है कि "एक कार्यान्वयन विवरण" एक फ़ॉन्ट-आकार होना चाहिए: 50 पीएक्स। ;)
सिसवे

2

ये @P डैडी द्वारा उत्तर के ऊपर दिखाए गए चित्र हैं

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

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

और मैंने अपनी शैली में संबंधित सामग्री को चित्रित किया।

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


@ पी डैडी I ने चित्र बनाए। कृपया जाँचें कि क्या गलत हिस्सा है। और मेरे कुछ अतिरिक्त प्रश्न हैं। 1. जब मैं 4 लंबाई इंट प्रकार सरणी बनाता हूं, तो लंबाई की जानकारी (4) भी हमेशा मेमोरी में संग्रहीत होती है?
यंगमिन पार्क

2. दूसरे चित्रण में, कॉपी किए गए सरणी पते को कहाँ संग्रहीत किया जाता है? क्या यह वही स्टैक क्षेत्र है जिसमें अंतर पता संग्रहीत है? क्या यह अन्य स्टैक है लेकिन उसी तरह का स्टैक है? क्या यह विभिन्न प्रकार का ढेर है? 3. कम 32-बिट्स / उच्च 32-बिट्स का क्या मतलब है? 4. जब मैं नए कीवर्ड का उपयोग करके स्टैक पर मूल्य प्रकार (इस उदाहरण, संरचना में) आवंटित करता हूं तो क्या रिटर्न वैल्यू है? क्या इसका भी पता है? जब मैं इस कथन Console.WriteLine (ValType) द्वारा जाँच कर रहा था, तो यह ConsoleApp.ValType जैसी ऑब्जेक्ट की तरह पूरी तरह से योग्य नाम दिखाएगा।
यंगमिन पार्क

5. वेलटाइप। I = 200; क्या इस कथन का अर्थ है कि मुझे वैल टाइप का पता मिलता है, इस पते से मैं I तक पहुंचता हूं और वहीं मैं 200 पर "स्टैक पर" स्टोर करता हूं।
यंगमिन पार्क

1

पूर्णांक का एक सरणी ढेर पर आवंटित किया जाता है, अधिक कुछ नहीं, कुछ भी कम नहीं। myIntegers उस खंड की शुरुआत का संदर्भ देता है जहाँ पर इनट्स आवंटित किए जाते हैं। यह संदर्भ स्टैक पर स्थित है।

यदि आपके पास ऑब्जेक्ट प्रकार की तरह संदर्भ ऑब्जेक्ट्स की एक सरणी है, तो स्टैक पर स्थित myObjects [], मानों के झुंड का संदर्भ देगा जो ऑब्जेक्ट्स को स्वयं संदर्भित करता है।

संक्षेप में, यदि आप कुछ कार्यों के लिए myIntegers पास करते हैं, तो आप केवल उस जगह के संदर्भ को पास करते हैं जहां पूर्णांक का वास्तविक गुच्छा आवंटित किया गया है।


1

आपके उदाहरण कोड में कोई बॉक्सिंग नहीं है।

मूल्य प्रकार ढेर पर रह सकते हैं जैसा कि वे आपके ints के सरणी में करते हैं। सरणी को ढेर पर आवंटित किया गया है और यह ints को संग्रहीत करता है, जो मूल्य प्रकार के होते हैं। सरणी की सामग्री को डिफ़ॉल्ट (int) के लिए प्रारंभ किया जाता है, जो शून्य होता है।

उस वर्ग पर विचार करें, जिसमें एक मूल्य प्रकार है:


    class HasAnInt
    {
        int i;
    }

    HasAnInt h = new HasAnInt();

वैरिएबल एच, हसअनेंट के एक उदाहरण को संदर्भित करता है जो ढेर पर रहता है। यह केवल एक मूल्य प्रकार समाहित करने के लिए होता है। यह पूरी तरह से ठीक है, 'मैं' सिर्फ ढेर पर रहने के लिए होता है क्योंकि यह एक वर्ग में निहित है। इस उदाहरण में कोई बॉक्सिंग नहीं है।


1

पर्याप्त हर किसी के द्वारा कहा गया है, लेकिन अगर किसी को ढेर, ढेर, स्थानीय चर और स्थिर चर के बारे में एक स्पष्ट (लेकिन गैर-आधिकारिक) नमूना और दस्तावेज की तलाश है , तो .NET में मेमोरी पर पूरा जॉन स्कीट का लेख देखें - क्या जाता है कहाँ पे

अंश:

  1. प्रत्येक स्थानीय चर (यानी एक विधि में घोषित) स्टैक पर संग्रहीत होता है। इसमें संदर्भ प्रकार चर शामिल हैं - चर स्वयं स्टैक पर है, लेकिन याद रखें कि एक संदर्भ प्रकार चर का मूल्य केवल एक संदर्भ (या अशक्त) है, न कि वस्तु। विधि पैरामीटर स्थानीय चर के रूप में भी गिना जाता है, लेकिन अगर उन्हें रेफ संशोधक के साथ घोषित किया जाता है, तो उन्हें अपना स्लॉट नहीं मिलता है, लेकिन कॉलिंग कोड में उपयोग किए गए चर के साथ एक स्लॉट साझा करते हैं। अधिक विवरण के लिए पासिंग पैरामीटर पर मेरा लेख देखें।

  2. संदर्भ प्रकार के लिए इंस्टेंस चर हमेशा ढेर पर होते हैं। बस यहीं वस्तु "जीवन" है।

  3. मान प्रकार के लिए इंस्टेंस चर उसी संदर्भ में संग्रहीत किए जाते हैं, जो मान प्रकार घोषित करता है। उदाहरण के लिए मेमोरी स्लॉट में प्रभावी रूप से प्रत्येक क्षेत्र के लिए स्लॉट हैं। इसका मतलब है (पिछले दो बिंदुओं को देखते हुए) कि एक विधि के भीतर घोषित एक संरचनात्मक चर हमेशा स्टैक पर होगा, जबकि एक संरचनात्मक चर जो वर्ग का एक उदाहरण क्षेत्र है ढेर पर होगा।

  4. प्रत्येक स्थिर चर को ढेर पर संग्रहीत किया जाता है, भले ही यह संदर्भ प्रकार या मूल्य प्रकार के भीतर घोषित किया गया हो। कुल कितने ही उदाहरण बनते हैं, केवल एक ही स्लॉट होता है। (हालांकि उस एक स्लॉट के अस्तित्व के लिए किसी भी उदाहरण को बनाने की आवश्यकता नहीं है।) वास्तव में जो चर पर रहते हैं, उनका विवरण जटिल है, लेकिन इस विषय पर एक MSDN लेख में विस्तार से बताया गया है।

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