关闭

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

396人阅读 评论(0) 收藏 举报

内存分配:内存中,存在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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:10147次
    • 积分:168
    • 等级:
    • 排名:千里之外
    • 原创:8篇
    • 转载:1篇
    • 译文:0篇
    • 评论:2条
    文章分类
    文章存档