C#中struct与class

panwen516 2008-04-11 12:36: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代码明显多了两行,既然是初始化但也要给它分配空间呀,那是什么时候分的呢?
...全文
212 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
财富实验室 2008-04-17
  • 打赏
  • 举报
回复
1=2-1
return 1

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

财富实验室 2008-04-17
  • 打赏
  • 举报
回复
new不new应该没关系。
ai0ai 2008-04-17
  • 打赏
  • 举报
回复
结构在创建时就给划分好内存空间了
panwen516 2008-04-17
  • 打赏
  • 举报
回复
IL_0001: newobj instance void StructAndClass.ClassText::.ctor()

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

实例化一个方法时调用了构造方法,并为对象分配内存。
  • 打赏
  • 举报
回复

00000006 sub esp,3Ch //分配局部变量内存

0000006e lea esp,[ebp-0Ch]//恢复esp
局部变量就失效了
也就是说在进入函数的时候分配内存,在定义的地方初始化
在return之后释放内存.
panwen516 2008-04-17
  • 打赏
  • 举报
回复
如果类是在使用的时候分配的内存,那结构呢?
它也是在使用的时候给分配的吗?


Assembly code

看不懂,能简单解释一下吗?
zhujiechang 2008-04-16
  • 打赏
  • 举报
回复
类是在使用时才分配具体内存,开始实例化只是进行一个指针的初始化而已。
楼主可能认为类在初始化时就分配了所有足够运行的内存,实际上并没有
  • 打赏
  • 举报
回复
调试的时候,看的汇编编码

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 的时候局部变量都没了.
panwen516 2008-04-16
  • 打赏
  • 举报
回复
没有人知道吗?
Lixin19821010 2008-04-14
  • 打赏
  • 举报
回复
按照我的理解:值类型在栈内分配内存,引用都是在堆分配内存,在栈内分配指向该引用的指针.
panwen516 2008-04-14
  • 打赏
  • 举报
回复
那是什么时候分配的呢?类的话有IL_0001: newobj instance void StructAndClass.ClassText::.ctor()
这句话在内存分配,但结构只有初始化,难道那就是内存分配吗?
lyq198345 2008-04-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 Fibona 的回复:]
struct 类型是一种值类型,通常用来封装小型相关变量组
[/Quote]

struct 类型是一种值类型,通常用来封装小型相关变量组
大小最好不要超过16个字节。
Fibona 2008-04-11
  • 打赏
  • 举报
回复
struct 类型是一种值类型,通常用来封装小型相关变量组
fengniumaxi 2008-04-11
  • 打赏
  • 举报
回复
new之后照样是在栈中分配
bingshan24 2008-04-11
  • 打赏
  • 举报
回复
IL代码... 不懂.~

110,532

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧