C#中struct的内存分配

时间:2021-06-14 02:22:33
请问结构类型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代码明显多了两行,既然是初始化但也要给它分配空间呀,那是什么时候分的呢?

5 个解决方案

#1


引用楼主 panwen516 的帖子:
请问结构类型new 与不new 在内存中有什么区别吗?值类型是在栈里面分配空间,结构是值类型如果new了后还是在栈里面分配空间吗?  
下面是两份代码,第一份结构类型没有new直接给它里面的引用类型传引用。第二份是结构类型new了后在给它里面的引用类型传引用。从IL代码中我们可以看到是有区别的,因为对IL还不太熟悉,不知道它们内存怎么分配的,而且也不知道是在什么时候分配的,所以望高人指点。  


1.结构类型分配在stack,类分配在heap。
2.结构不用new ,如:Stuct s 只是定义了一个Stuct 类型的引用。内容为null.如果Stuct s = new Stuct()就是在stack上给Stuct分配了空间

#2


new了在堆里面存 栈里面只是它的对象引用。

#3


不是的,在C#中内存分配跟代码没有关系(如:new),它只跟类型有关。

#4


没遇到过这种情况.

#5


该回复于2008-05-05 14:27:41被版主删除

#1


引用楼主 panwen516 的帖子:
请问结构类型new 与不new 在内存中有什么区别吗?值类型是在栈里面分配空间,结构是值类型如果new了后还是在栈里面分配空间吗?  
下面是两份代码,第一份结构类型没有new直接给它里面的引用类型传引用。第二份是结构类型new了后在给它里面的引用类型传引用。从IL代码中我们可以看到是有区别的,因为对IL还不太熟悉,不知道它们内存怎么分配的,而且也不知道是在什么时候分配的,所以望高人指点。  


1.结构类型分配在stack,类分配在heap。
2.结构不用new ,如:Stuct s 只是定义了一个Stuct 类型的引用。内容为null.如果Stuct s = new Stuct()就是在stack上给Stuct分配了空间

#2


new了在堆里面存 栈里面只是它的对象引用。

#3


不是的,在C#中内存分配跟代码没有关系(如:new),它只跟类型有关。

#4


没遇到过这种情况.

#5


该回复于2008-05-05 14:27:41被版主删除