首页 > 代码库 > 内存管理与不安全代码
内存管理与不安全代码
***************************************内存管理**********************************************************
===================================栈:
1,存储着值类型(方法的参数存储在栈中)
2,高性能
3,生存周期必须嵌套(缺点)
结构是值类型,存储在栈中。结构实例化(new)不会在栈中分配空间
===================================托管堆(与传统的堆相比有很显著的优势):
1,存储着引用类型(对象成员的值类型也存储在堆上)
2,可以对数据的生存周期进行强大的控制
3,建立引用变量的过程比建立值变量的过程复杂,性能开销大
===================================析构函数(必须有垃圾回收器调用):
1,垃圾回收器销毁对象之前执行
2,c#无法确定垃圾回收器何时执行,不能在析构函数中放置 需要在某一时刻执行的代码
3,c#析构函数的实现,会延迟对象从内存中销毁的时间。
4,频繁使用析构函数,对性能会有影响
===================================垃圾回收器
System.GC.Collect(); //强制对所有代进行垃圾回收
System.GC.SuppressFinalize(object); //不掉用对象的终结器(析构函数)
***************************************不安全代码**********************************************************
===================================1,用unsafe关键字编写不安全代码
//配置:选中项目反键->属性->生成->勾选允许不安全代码
//标记类 unsafe public class Student { //标记字段 unsafe int* pAge; //标记方法 unsafe void getType(int* a) { //标记代码段 unsafe { int* pAbc; //声明指针语法 } } }
===================================2,指针的语法
unsafe { int* pWidth, pHeight; double* pResult; byte*[] pByte; //&:表示“取地址”,并把一个值数据类型转换为指针,例如,int转换为*int。这个运算称为【寻址运算符】 //*:表示“获取地址内容”,把一个指针转换为一个值数据类型(例如:*float转换为float)。这个运算符被 //称为“间接寻址运算符”(有时称“取消引用运算符”) int a = 10;//声明一个值类型,给它赋值10 int* pA, pB;//声明2个指针 pA = &a;//取出值类型a的地址,赋值给指针pA pB = pA;//把指针pA的地址赋值给pB *pB = 20;//获取pB指向的地址内容,并赋值20 Console.WriteLine(a);//输出20 }
===================================3,将指针强制转化为整数类型
//只能转化为uing、long、ulong类型
int a = 10; int* pA, pB; pA = &a; uint address = (uint)pA;//将指针地址强制转换为整数类型 pB = (int*)address;//将整数类型强制转换为指针 *pB = 20;//指针指向a Console.WriteLine(a);//输出20
===================================4,指针类型的强制装换
int b = 10; int* pIa; double* pDa; pIa = &b; pDa = (double*)pIa;//将int*强制转换成double*
===================================5,void指针(不指向任何数据类型的指针)
int c = 10; int* pAA; pAA = &c; void* pVa = (void*)pAA;//转换viod指针
===================================6,指针算数的运算(不允许对void指针进行运算)
p+x*(sizeof(T))
p:指针的地址
x:加上的数值
T:类型的大小
int d = 10; int* pId;//如果地址为100000 pId = &d; pId++;//结果:100004(int类型的大小为4个字节)
===================================7,sizeof运算符(只能求出值类型的大小)
int x = sizeof(int);
===================================8,结构指针:指针成员访问运算符
①指针不能只想任何引用类型
②结构里面不能包含引用类型
MyStruct* pStruct; MyStruct ms = new MyStruct(); pStruct = &ms; //--取地址内容赋值为10 (*pStruct).X = 10; pStruct->X = 10; //--取地址赋值给pIs int* pIs1 = &(ms.X); int* pIs2 = &(pStruct->X); //结构 struct MyStruct { public int X = 1; public int Y = 2; }
===================================9,类成员指针
Person p = new Person(); fixed (int* pIp1 = &(p.X), pIp2 = &(p.Y)) { }//pIp1和pIp2的生命周期 //类 class Person { public int X; public int Y; }
===================================有趣的实验
unsafe { //有趣的问题:为什么b的值改变了 //回答:因为i的地址指向了b int a = 10; int b = 20; int* i; i = &a;//将a的地址赋值给指针i i -= 1;//将i的地址-1(相当于向下移动4个字节(int类型的大小为4个字节)) *i = 30;//取出i指针指向的内容赋值为30 Console.WriteLine(b);//输出30 }
本文出自 “程序猿的家--Hunter” 博客,请务必保留此出处http://962410314.blog.51cto.com/7563109/1567425
内存管理与不安全代码