版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第C#通过不安全代码看内存加载的示例详解目录项目文件值类型自定义结构体引用类型string自定class类型C#中类型分为值类型和引用类型,值类型存储在堆栈中,是栈结构,先进后出,引用类型存储在托管堆中。接下来用不安全代码的地址,来看一下值类型和引用类型的存储。
项目文件
C#中使用不安全代码需要在项目文件中添加AllowUnsafeBlocks配置。
ProjectSdk="Microsoft.NET.Sdk"
PropertyGroup
OutputTypeExe/OutputType
TargetFrameworknet7.0/TargetFramework
ImplicitUsingsenable/ImplicitUsings
Nullableenable/Nullable
AllowUnsafeBlockstrue/AllowUnsafeBlocks
/PropertyGroup
/Project
所有的测试案例都是定义两个特定类型的变量,然后查看它的内存地址,然后进行调用一个方法进行相加运算,然后分别在方法内输出变量和结查内存地址,最后返回主方法后变量的内存地址。
值类型
staticvoidTestDouble()
varv1=1.00001d;
varv2=2.00002d;
Console.WriteLine("TestDoublev1"+(long)v1);
Console.WriteLine("TestDoublev2"+(long)v2);
Console.WriteLine("TestDoublev2-v1"+((long)v2-(long)v1));
varv3=Add(v1,v2);
Console.WriteLine("TestDoublev3"+(long)v3);
Console.WriteLine("TestDoublev3-v2"+((long)v3-(long)v2));
Console.WriteLine("TestDoublev3-v1"+((long)v3-(long)v1));
staticdoubleAdd(doublev1,doublev2)
Console.WriteLine("Addv1"+(long)v1);
Console.WriteLine("Addv2"+(long)v2);
Console.WriteLine("Addv2-v1"+((long)v2-(long)v1));
varv3=v1+v2;
Console.WriteLine("Addv3"+(long)v3);
Console.WriteLine("Addv3-v2"+((long)v3-(long)v2));
Console.WriteLine("Addv3-v1"+((long)v3-(long)v1));
returnv3;
}
v1的所在内存地址大于v2,最后运算完的v3是最小的,我们可以想象,v1放在栈的最后面,地址最大,然后放v2,最后放v3。回收时的顺序是反回来的。那么Add方法里,v2地址最大,但比TestDouble都要小,说明进栈要晚一些,接下来是v1进栈,最后是v3进栈,不过TestDouble里的每个变量都相差8,但方法里的就不是了,这是因为方法参数,返回值等信息,还要占一些内存空间。还有TestDouble的v3为什么能和v2相差8?不是有Add方法吗?原因是Add调用完后都出栈了,所以TestDouble的v3和v2是相邻的。
自定义结构体
structTestStruct
publicTestStruct()
i=100;
publiclongi;
staticvoidTestTestStruct()
varv1=newTestStruct();
Console.WriteLine("TestStruct原v1对象地址="+(long)v1);
varv2=newTestStruct();
Console.WriteLine("TestStruct原v2对象地址="+(long)v2);
Console.WriteLine("TestStructv2-v1"+((long)v2-(long)v1));
varv3=Add(v1,v2);
Console.WriteLine("TestStruct原v3对象地址="+(long)v3);
Console.WriteLine("TestStructv3-v2"+((long)v3-(long)v2));
staticTestStructAdd(TestStructv1,TestStructv2)
Console.WriteLine("AddTestStructv1对象地址="+(long)v1);
Console.WriteLine("AddTestStructv2对象地址="+(long)v2);
Console.WriteLine("AddTestStructv2-v1"+((long)v2-(long)v1));
varv3=newTestStruct();
v3.i=v1.i+v2.i;
Console.WriteLine("AddTestStructv3对象地址"+(long)v3);
Console.WriteLine("AddTestStructv3-v2"+((long)v3-(long)v2));
returnv3;
}
自定义struct与double类似,本质上double也是用struct定义的。
引用类型string
staticvoidTestString()
longad1,ad2,ad3;
varv1="aaaa";
varv2="bbbb";
fixed(char*p=v1)
ad1=(long)p;
Console.WriteLine("TestStringv1字符串地址="+(long)p);
fixed(char*p=v2)
ad2=(long)p;
Console.WriteLine("TestStringv2字符串地址="+(long)p);
Console.WriteLine("TestStringv2-v1"+(ad2-ad1));
varv3=Add(v1,v2);
fixed(char*p=v3)
ad3=(long)p;
Console.WriteLine("TestStringv3字符串地址="+(long)p);
Console.WriteLine("TestStringv3-v2"+(ad3-ad2));
staticstringAdd(stringv1,stringv2)
longad1,ad2,ad3;
fixed(char*p=v1)
ad1=(long)p;
Console.WriteLine("Add中v1字符串地址="+(long)p);
fixed(char*p=v2)
ad2=(long)p;
Console.WriteLine("Add中v2字符串地址="+(long)p);
Console.WriteLine("Add中v2-v1"+(ad2-ad1));
varv3=v1+v2;
fixed(char*p=v3)
ad3=(long)p;
Console.WriteLine("Add中v3字符串地址="+(long)p);
Console.WriteLine("Add中v3-v2"+(ad3-ad2));
Console.WriteLine("Add中v3-v1"+(ad3-ad1));
returnv3;
staticvoidTestString2()
varv1="aaaa";
varv2="bbbb";
varh1=GCHandle.Alloc(v1,GCHandleType.Pinned);
Console.WriteLine("TestString2v1对象地址="+(long)h1.AddrOfPinnedObject());
varh2=GCHandle.Alloc(v2,GCHandleType.Pinned);
Console.WriteLine("TestString2v2对象地址="+(long)h2.AddrOfPinnedObject());
Console.WriteLine("TestString2v2-v1"+((long)h2.AddrOfPinnedObject()-(long)h1.AddrOfPinnedObject()));
varv3=Add2(v1,v2);
varh3=GCHandle.Alloc(v3,GCHandleType.Pinned);
Console.WriteLine("TestString2v3对象地址="+(long)h3.AddrOfPinnedObject());
Console.WriteLine("TestString2v3-v2"+((long)h3.AddrOfPinnedObject()-(long)h2.AddrOfPinnedObject()));
staticstringAdd2(stringv1,stringv2)
varh1=GCHandle.Alloc(v1,GCHandleType.Pinned);
Console.WriteLine("Add2中的v1对象地址="+(long)h1.AddrOfPinnedObject());
varh2=GCHandle.Alloc(v2,GCHandleType.Pinned);
Console.WriteLine("Add2中的v2对象地址="+(long)h2.AddrOfPinnedObject());
Console.WriteLine("Add2v2-v1"+((long)h2.AddrOfPinnedObject()-(long)h1.AddrOfPinnedObject()));
varv3=v1+v2;
varh3=GCHandle.Alloc(v3,GCHandleType.Pinned);
Console.WriteLine("Add2中的v3对象地址="+(long)h3.AddrOfPinnedObject());
Console.WriteLine("Add2v3-v2"+((long)h3.AddrOfPinnedObject()-(long)h2.AddrOfPinnedObject()));
Console.WriteLine("Add2v3-v1"+((long)h3.AddrOfPinnedObject()-(long)h1.AddrOfPinnedObject()));
returnv3;
}
字符串是引用类型,v1比v2内存地址小,进入Add后,v1和v2与传入的地址相同,因为是引用类型,Add方法里的v3接着往大走,并且与返回的v3是一个地址,这些没有问题。
string用了两种方法,发现两个方式v1都是aaaa,v2都是bbbb,因为字符串有留用性,所以两个方法的v1和v2是一样的;但两种方式调用了Add后,在Add里的v3都是aaaabbbb,都是拼接,但拼出来的字符串的地址不相同,所以这块没有留用。
自定class类型
classTestClass
publicinti=100;
staticvoidTestTestClass()
varv1=newTestClass();
varh1=GCHandle.Alloc(v1,GCHandleType.Pinned);
Console.WriteLine("TestTestClassv1对象地址="+(long)h1.AddrOfPinnedObject());
varv2=newTestClass();
varh2=GCHandle.Alloc(v2,GCHandleType.Pinned);
Console.WriteLine("TestTestClassv2对象地址="+(long)h2.AddrOfPinnedObject());
Console.WriteLine("TestTestClassv2-v1"+((long)h2.AddrOfPinnedObject()-(long)h1.AddrOfPinnedObject()));
varv3=Add(v1,v2);
varh3=GCHandle.Alloc(v3,GCHandleType.Pinned);
Console.WriteLine("TestTestClass3对象地址="+(long)h3.AddrOfPinnedObject());
Console.WriteLine("TestTestClassv3-v2"+((long)h3.AddrOfPinnedObject()-(long)h2.AddrOfPinnedObject()));
staticTestClassAdd(TestClassv1,TestClassv2)
varh1=GCHandle.Alloc(v1,GCHandleType.Pinned);
Console.WriteLine("Add中的v1对象地址="+(long)h1.AddrOfPinnedObject());
varh2=GCHandle.Alloc(v2,GCHandleType.Pinned);
Console.WriteLine("Add
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年食堂安全培训内容简报重点
- 2026年空调安全培训内容重点
- 植树节环保主题演讲稿600字7篇
- 博尔塔拉蒙古自治州博乐市2025-2026学年第二学期六年级语文第五单元测试卷部编版含答案
- 2026年出货安全培训内容从零到精通
- 邢台市宁晋县2025-2026学年第二学期六年级语文第五单元测试卷部编版含答案
- 益阳市沅江市2025-2026学年第二学期六年级语文第五单元测试卷部编版含答案
- 衡阳市衡南县2025-2026学年第二学期五年级语文第六单元测试卷(部编版含答案)
- 宜春市樟树市2025-2026学年第二学期六年级语文第五单元测试卷部编版含答案
- 银川市兴庆区2025-2026学年第二学期五年级语文第六单元测试卷(部编版含答案)
- 国开2026年《公共政策概论》形成性考核任务1-4答案
- 2026贵州贵阳经济开发区招聘工作人员20名考试参考题库及答案解析
- 云南省西南名校联盟2026届高三下学期3月联考语文试卷(含答案)
- 2026年山西运城农业职业技术学院单招综合素质考试题库含答案详细解析
- 2025年浙江省宁波市海曙区统编版六年级下册小升初考试语文试卷
- 窦性心律失常护理方案
- 湖北省武汉市2026届高三下学期三月调研考试语文试题(含答案)
- 道路工程土方施工方案(3篇)
- 肿瘤姑息治疗2025年CSCO指南
- 卫生室统计信息管理制度
- 两票实施细则培训课件
评论
0/150
提交评论