2011-03-09 7 views
12

मैं स्ट्रिंग प्रकार के मेमोरी लेआउट को जांचने के लिए एसओएस डीबग एक्सटेंशन डीएल का उपयोग कर रहा हूं। और नीचे परिणाम है।.NET स्ट्रिंग मान कहां रखता है?

!

ESP/REG Object Name 

0015EFC0 01c6b9cc System.String hello,world 

DSO!, 01c6b9cc

Name:  System.String 

MethodTable: 6de3f9ac 

EEClass:  6db78bb0 

Size:  36(0x24) bytes 

File:  C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089>\mscorlib.dll 

String:  hello,world 

Fields: 
     MT Field Offset     Type VT  Attr Value Name 

6de42978 40000ed  4   System.Int32 1 instance  11 m_stringLength 

6de41dc8 40000ee  8   System.Char 1 instance  68 m_firstChar 

6de3f9ac 40000ef  8  System.String 0 shared static Empty 

    >> Domain:Value 00331488:01c61228 << 

अब मैं सोच रहा हूँ कर जहां वास्तव में स्ट्रिंग मान "हैलो दुनिया" संग्रहीत किया जाता है है?

धन्यवाद।

+0

संभवतः ढेर पर कहीं और 'char []', मुझे लगता है। – Joey

उत्तर

12

m_firstChar पर। ढेर आवंटन पूरी स्ट्रिंग फिट करने के लिए काफी बड़ा है, न केवल पहले चरित्र। दृश्य स्टूडियो में देखने के लिए और साथ ही आसान:

class Program { 
    static void Main(string[] args) { 
     string s = "hello" + "world"; 
    } // <=== Breakpoint here 
} 

जब ब्रेकप्वाइंट हिट, डीबग + विंडोज + मेमोरी + Memory1 का उपयोग करें। पता बॉक्स प्रकार एस में। आप देखेंगे:

0x01B3F6BC e8 0a 67 6e 0b 00 00 00 0a 00 00 00 68 00 65 00 è.gn........h.e. 
0x01B3F6CC 6c 00 6c 00 6f 00 77 00 6f 00 72 00 6c 00 64 00 l.l.o.w.o.r.l.d. 
  • वस्तु का पता पर शुरू होता है -, 4 syncblk वहाँ संग्रहीत किया जाता है (दिखाई नहीं)।
  • अगले 4 बाइट्स विधि तालिका सूचक (0x6e670ae8, उर्फ ​​प्रकार संभाल) है।
  • अगले 4 बाइट्स m_arrayLength सदस्य, स्ट्रिंग (0x0b) की आवंटित आकार है।
  • अगले 4 बाइट्स m_stringLength सदस्य, स्ट्रिंग (0x0A) में पात्रों की वास्तविक संख्या है।
  • अगला बाइट स्ट्रिंग को स्टोर करते हैं, जो m_firstChar से शुरू होता है।

यह .NET 3.5 SP1 के लिए है। आपको .NET 4.0 और ऊपर में m_arrayLength सदस्य नहीं दिखाई देगा, फ़ील्ड हटा दिया गया था।

+0

आपकी व्याख्या के लिए धन्यवाद। मुझे नहीं पता था कि मैंने कल m_firstChar क्यों नहीं देखा ... इसके अलावा, मैं .NET 4.0 का उपयोग कर रहा हूं। – smwikipedia

+3

ठीक है जो इसे समझाता है, .NET 4.0 ने m_arrayLength फ़ील्ड को छोड़ दिया। –

3

एक सी "स्ट्रिंग" की तरह, यह m_stringLength बाइट्स m_firstChar से शुरू होता है जो एक असुरक्षित सूचक है, वास्तविक चरित्र नहीं। सी # null की बजाय एक लंबाई पूर्ववर्ती स्ट्रिंग का उपयोग करता है हालांकि सीमित है।

कहा कि, CLR की सुंदरता है कि आप देखभाल करने के लिए की जरूरत नहीं है है। यह कैसे एक मुद्दा बन गया है?

+0

m_firstChar एक सूचक नहीं है। स्ट्रिंग के वर्ण स्ट्रिंग ऑब्जेक्ट में एम्बेडेड हैं, m_firstChar से शुरू होते हैं। –

+0

@ हंस तो मैं आपके उत्तर से देखता हूं, लेकिन यह कैसे काम करता है? वस्तुओं को एक निश्चित लंबाई की आवश्यकता नहीं है? –

+0

ऐसी कोई आवश्यकता नहीं है। सर्वश्रेष्ठ उदाहरण एक सरणी है। ये हालांकि चाल हैं कि सीएलआर खेल सकता है लेकिन हमारे लिए उपलब्ध नहीं है। –

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