[笔记]dotNET内存的分配、指针

内存分配:内存中,存在Stack和Heap两种不同分配方式。实值(int, long, short等)存于Stack中,引用类型(比如类)的首地址存于Stack中,占用4字节,这个地址指向了Heap中值的地址,而该引用的实值存于Heap中。

Stack存储顺序为高位到低位,包含了一个系统指针,这个指针指向了所使用的Stack的最低位。Heap存储顺序为低位到高位,包含一个系统指针,这个指针指向所使用的Heap的最高位。

DWORD: 在32位的处理器上,它占用4字节,相当于一个无符号整数。在Windows系统中,DWORD成为最基本的内存分配单位。

值得注意的是,dotNET为每一个变量分配的内存都是4字节(或者是4字节的整数倍)。如果所申请的变量需要小于4字节,dotNET也会分配一个4字节空间给这个变量。比如说,如果你要求一个byte,虽然它是8位,系统一样会分配一个4字节的空间给它。

从这里可以发现,整数依然是最有效率的,尽量使用整数可以提高系统的效率。

指针在32位处理器上,一个指针占用4字节空间,相当于一个无符号整数,也就是说,指针可以强制转化为一个无符号的整数。这样就可以把这个地址显示出来。转化如下:int* pX; uint addrx = (uint)pX;

结构指针:在使用结构指针的时候,该结构不能包含引用类型(Class)值,否则编译器提示错误。

struct MyStruct
{
   public long X;
   public float F;
}

使用结构指针

MyStruct* pStruct;
MyStruct Struct = new MyStruct();
pStruct = &Struct;

使用指针修改结构内的值的几种方法

(*pStruct).X = 4;
(*pStruct).F = 5.2;

pStruct -> X = 4;
pStruct -> F = 5.2;

long* pX = &(Struct.X);
float* pF = &(Struct.F);

long* pX = &(pStruct->X);
float* pF = &(pStruct->F);

类指针:C#中不存在类指针的概念,由于类属于托管类型,它的建立和回收都取决于dotNET的GC(Garbage Collector)对它的管理,所以指向一个类的指针没有实际的意义(因为类一旦被销毁,则程序中其他类所在的内存地址有可能会变化,这取决于GC如何进行作业)。但是,我们仍然可以使用指针来指向类中的某一个实值变量。

public class Apple
{
public Color color;
public float weight;
public string description;
}

 这里,我们可以建立指向weight和description的指针

Apple fruit = new Apple();
float* pw = &(fruit.weight);
string* pd = &(fruit.description);

我们刚才有提到,因为类属于托管类型,所以受到GC的约束,它本身的内存地址,甚至是它所包含的实值的地址都可能变动,而造成指针的失效。为了安全起见,在使用类中的实值创建指针的时候,我们可以使用fixed关键字,来使得它的地址在fixed的范围内不变动。

Apple fruit = new Apple();
fixed (float* pw = &(fruit.weight))
{
*pw = 0.3;
}

使用嵌套,同时锁定两个值

Apple fruit = new Apple();
fixed (float* pw = &(fruit.weight))
{
   fixed (string* dw = &(fruit.description))
   {
   }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值