请问结构类型new 与不new 在内存中有什么区别吗?值类型是在栈里面分配空间,结构是值类型如果new了后还是在栈里面分配空间吗?
下面是两份代码,第一份结构类型没有new直接给它里面的引用类型传引用。第二份是结构类型new了后在给它里面的引用类型传引用。从IL代码中我们可以看到是有区别的,因为对IL还不太熟悉,不知道它们内存怎么分配的,而且也不知道是在什么时候分配的,所以望高人指点。using System;
using System.Collections.Generic;
using System.Text;
using System.Data;namespace StructAndClass
{
    class Program
    {
        static void Main(string[] args)
        {            ClassText classText;
             classText   = new ClassText();
            classText.num = 5;
            classText.name = "Hello";            StructText structText;
            structText.classText = classText;
           
        }
    }    public class ClassText
    {
        public int num;
        public string name;
       
    }    public struct StructText
    {
        public ClassText classText;
        public int n;
    }
}Main函数的IL代码.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // 代码大小       34 (0x22)
  .maxstack  2
  .locals init (class StructAndClass.ClassText V_0,
           valuetype StructAndClass.StructText V_1)
  IL_0000:  nop
  IL_0001:  newobj     instance void StructAndClass.ClassText::.ctor()
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  ldc.i4.5
  IL_0009:  stfld      int32 StructAndClass.ClassText::num
  IL_000e:  ldloc.0
  IL_000f:  ldstr      "Hello"
  IL_0014:  stfld      string StructAndClass.ClassText::name
  IL_0019:  ldloca.s   V_1
  IL_001b:  ldloc.0
  IL_001c:  stfld      class StructAndClass.ClassText StructAndClass.StructText::classText
  IL_0021:  ret
} // end of method Program::Main
第二份代码using System;
using System.Collections.Generic;
using System.Text;
using System.Data;namespace StructAndClass
{
    class Program
    {
        static void Main(string[] args)
        {            ClassText classText;
             classText   = new ClassText();
            classText.num = 5;
            classText.name = "Hello";            StructText structText = new StructText();
            structText.classText = classText;
            int x = structText.n;
           
        }
    }    public class ClassText
    {
        public int num;
        public string name;
       
    }    public struct StructText
    {
        public ClassText classText;
        public int n;
    }
}Main函数的IL代码
.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // 代码大小       42 (0x2a)
  .maxstack  2
  .locals init (class StructAndClass.ClassText V_0,
           valuetype StructAndClass.StructText V_1)
  IL_0000:  nop
  IL_0001:  newobj     instance void StructAndClass.ClassText::.ctor()
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  ldc.i4.5
  IL_0009:  stfld      int32 StructAndClass.ClassText::num
  IL_000e:  ldloc.0
  IL_000f:  ldstr      "Hello"
  IL_0014:  stfld      string StructAndClass.ClassText::name
  IL_0019:  ldloca.s   V_1
  IL_001b:  initobj    StructAndClass.StructText
  IL_0021:  ldloca.s   V_1
  IL_0023:  ldloc.0
  IL_0024:  stfld      class StructAndClass.ClassText StructAndClass.StructText::classText
  IL_0029:  ret
} // end of method Program::Main
第二份IL代码明显多了两行,既然是初始化但也要给它分配空间呀,那是什么时候分的呢?

解决方案 »

  1.   

    struct 类型是一种值类型,通常用来封装小型相关变量组
      

  2.   


    struct 类型是一种值类型,通常用来封装小型相关变量组
    大小最好不要超过16个字节。
      

  3.   

    那是什么时候分配的呢?类的话有IL_0001:  newobj     instance void StructAndClass.ClassText::.ctor() 
    这句话在内存分配,但结构只有初始化,难道那就是内存分配吗?
      

  4.   

    调试的时候,看的汇编编码 static void func()
    {
    00000000  push        ebp  
    00000001  mov         ebp,esp//保存了esp到ebp中 
    00000003  push        edi  
    00000004  push        esi  
    00000005  push        ebx  
    00000006  sub         esp,3Ch //分配局部变量内存
    00000009  xor         eax,eax 
    0000000b  mov         dword ptr [ebp-44h],eax 
    0000000e  mov         dword ptr [ebp-40h],eax 
    00000011  mov         dword ptr [ebp-10h],eax 
    00000014  xor         eax,eax 
    00000016  mov         dword ptr [ebp-1Ch],eax 
    00000019  cmp         dword ptr ds:[00A89200h],0 
    00000020  je          00000027 
    00000022  call        76D66D87 
    00000027  xor         ebx,ebx 
    00000029  xor         edx,edx 
    0000002b  mov         dword ptr [ebp-48h],edx 
    0000002e  nop              
    ClassText classText;
    classText = new ClassText();
    0000002f  mov         ecx,0A89E94h 
    00000034  call        FD6B0A5C 
    00000039  mov         esi,eax 
    0000003b  mov         ecx,esi 
    0000003d  call        FD6CB0E0 
    00000042  mov         ebx,esi 
    classText.num = 5;
    00000044  mov         dword ptr [ebx+8],5 
    classText.name = "Hello";
    0000004b  mov         eax,dword ptr ds:[023C3098h] 
    00000051  lea         edx,[ebx+4] 
    00000054  call        76AB3F70  StructText structText = new StructText();
    00000059  lea         edi,[ebp-44h] 
    0000005c  pxor        xmm0,xmm0 
    00000060  movq        mmword ptr [edi],xmm0 
    structText.classText = classText;
    00000064  mov         dword ptr [ebp-44h],ebx 
    int x = structText.n;
    00000067  mov         eax,dword ptr [ebp-40h] 
    0000006a  mov         dword ptr [ebp-48h],eax 
    }
    0000006d  nop              
    0000006e  lea         esp,[ebp-0Ch]//恢复esp 
    00000071  pop         ebx  
    00000072  pop         esi  
    00000073  pop         edi  
    00000074  pop         ebp  
    00000075  ret             //恢复esp 的时候局部变量都没了.
      

  5.   

    如果类是在使用的时候分配的内存,那结构呢?
    它也是在使用的时候给分配的吗?
    Assembly code看不懂,能简单解释一下吗?
      

  6.   


    00000006  sub         esp,3Ch //分配局部变量内存0000006e  lea         esp,[ebp-0Ch]//恢复esp 
    局部变量就失效了
    也就是说在进入函数的时候分配内存,在定义的地方初始化
    在return之后释放内存.
      

  7.   

    IL_0001:  newobj     instance void StructAndClass.ClassText::.ctor() .ctor()为构造方法,它有一个void返回值类型,并且除了this指针以外,没有任何其他参数。其中this指针指向构造器方法被调用时正在被构造的对象内存。
    ---《.NET框架程序设计》第二章44页。 实例化一个方法时调用了构造方法,并为对象分配内存。
      

  8.   

    1=2-1
    return 1跟 return 1
    肯定IL是不一样的。