[笔记]dotNET内存的分配、指针
2007-09-19 19:01
281 查看
内存分配:内存中,存在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))
{
}
}
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))
{
}
}
相关文章推荐
- 深入理解C指针学习笔记---多级指针的内存分配问题(五)
- C和指针之动态内存分配堆、栈、全局区(静态区)、常量区对比总结学习笔记
- C++库研究笔记——用C语言函数指针包装内存分配、释放
- 数据结构 学习笔记之:关于顺序栈中给结构体类型指针分配内存时,使用malloc和不使用malloc的疑惑之解惑!
- 内存分配 指针和数组对比
- c++内存空间分配与指针探讨
- JVM笔记4:Java内存分配策略
- 字符数组和字符指针在分配内存时的差别
- OpenCV源码之内存分配-指针对齐
- [delphi函数] Dispose 释放为指针分配的内存空间
- 由于未分配内存的指针导致段错误
- 指针数组&数组指针的分配内存及函数参数 C语言版
- 指针做形参做局部变量以及内存分配
- 使用malloc分别分配2KB,6KB的内存空间,打印指针地址
- 黑马程序员—C学习笔记—指针字符串与其内存细节
- 内存分配详解、指针与数组[C++][内存管理]
- 习题 8.19(1) 编写一个函数new,对n个字符开辟连续的存储空间,此函数应返回一个指针(地址),指向字符串开始的空间。new(n)表示分配n个字节的内存空间。
- 改变指针指向的字符内容、动态分配字符型指针变量内存空间
- 二维字符数组与二维整型数组在内存中的分配及指针的问题
- .NET 内存分配笔记