2011-03-09 17 views
12

Estoy usando SOS debug extension dll para verificar el diseño de la memoria de un tipo String. Y abajo está el resultado.¿Dónde coloca .NET el valor String?

! DSO

ESP/REG Object Name 

0015EFC0 01c6b9cc System.String hello,world 

! Do 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 << 

Ahora me pregunto, dónde está exactamente el valor de cadena "hola mundo" se almacena?

Gracias.

+0

Probablemente un 'char []' en otro lugar en el montón, supongo. – Joey

Respuesta

12

En m_firstChar. La asignación del montón es lo suficientemente grande como para caber toda la cadena, no solo el primer carácter. Es fácil ver en Visual Studio, así:

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

Cuando los golpes de punto de interrupción, el uso de depuración de Windows + + + Memoria Memoria 1. En el cuadro Dirección, escriba s. Verás:

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. 
  • El objeto se inicia en la dirección - 4, el syncblk se almacena allí (no visible).
  • Siguiente 4 bytes es el puntero de la tabla de métodos (0x6e670ae8, aka handle de tipo).
  • Siguiente 4 bytes es el miembro m_arrayLength, el tamaño asignado de la cadena (0x0b).
  • Siguiente 4 bytes es el miembro m_stringLength, el número real de caracteres en la cadena (0x0a).
  • Los siguientes bytes almacenan la cadena, comenzando en m_firstChar.

Esto es para .NET 3.5 SP1. No verá el miembro m_arrayLength en .NET 4.0 y superior, el campo fue eliminado.

+0

Gracias por su explicación. No sabía por qué no noté el m_firstChar ayer ... Además, estoy usando .NET 4.0. – smwikipedia

+3

Bien, eso lo explica, .NET 4.0 dejó caer el campo m_arrayLength. –

3

Como una "cadena" C, se almacena en los bytes a partir de las m_stringLengthm_firstChar que es un puntero inseguro, no un carácter real. C# usa una cadena prefijada de longitud en lugar de una delimitada por null.

Dicho esto, la belleza de la CLR es que no necesita preocuparse. ¿Cómo se ha convertido esto en un problema?

+0

m_firstChar no es un puntero. Los caracteres de la cadena están incrustados en el objeto cadena, comenzando en m_firstChar. –

+0

@Hans, así que veo por su respuesta, pero ¿cómo funciona eso? ¿No es necesario que los objetos tengan una longitud fija? –

+0

no hay tal requisito. El mejor ejemplo es una matriz. Sin embargo, estos son trucos que el CLR puede jugar pero que no están disponibles para nosotros. –

Cuestiones relacionadas