打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
内存__【C#】不安全代码中的指针用法
有人说:"有的女人就像c#,长得很漂亮,但家务活不行。"  呵呵,其实我倒是认为不是那个女人不行,而是那个男人不行,征服不了那个女人。C#长得的确算漂亮,如果你驾驭了它,一样能让它服服帖帖做好家务。
    对于习惯C的程序员,Java之类的面向对象编程语言用着不是很爽,很多直接访问内存的操作行不通。而C#提供了指针的机制,以满足C族程序员的这点嗜好。不过刚开始了解到C#支持指针的时候,我也不以为然,总觉得这么搞显得不伦不类的。经过一番研究,慢慢感觉到了在一个有着强大基础类库的OO语言中使用指针的价值和威力。下面用代码展示一下使用指针的一些常用操作在C#中是怎么玩的,由于仅仅是展示,所以杂七杂八的代码全放在一起了。
view plaincopy to clipboardprint?
01. 1using System;  
02. 2  
03. 3namespace Sophy.UnsafeCode  
04. 4{  
05. 5    unsafe class Program  
06. 6    {  
07. 7        static void Main(string[] args)  
08. 8        {  
09. 9            //在栈上分配内存  
10.10            byte* arr_on_stack = stackalloc byte[100];  
11.11  
12.12            //下标访问数组  
13.13            for (int i = 0; i < 100; i++)  
14.14            {  
15.15                arr_on_stack[i] = 0;  
16.16            }  
17.17  
18.18            //在堆上分配内存  
19.19            fixed (byte* arr_on_heap = new byte[100])  
20.20            {  
21.21                //指针访问数组  
22.22                for (int i = 0; i < 100; i++)  
23.23                {  
24.24                    *(arr_on_heap + i) = 0;  
25.25                }  
26.26            }  
27.27  
28.28            //在栈上分配一个结构体  
29.29            Point p = new Point();  
30.30            //用结构体指针操作栈上的结构体  
31.31            Point* pp = &p;  
32.32            pp->x = 200;  
33.33            (*pp).y = 300;  
34.34  
35.35            //在堆上分配一个结构体  
36.36            fixed (byte* bs = new byte[sizeof(Point)])  
37.37            {  
38.38                //用结构体指针操作堆上的结构体  
39.39                Point* ph = (Point*)bs;  
40.40                (*ph).x = 400;  
41.41                ph->y = 500;  
42.42            }  
43.43  
44.44            //打印结构体内存地址  
45.45            Console.WriteLine("pp Memory Address: 0x{0:X}.", ((int)pp).ToString());  
46.46  
47.47            //识别CPU字节序  
48.48            pp->x = 1;  
49.49            byte* pb = (byte*)&(pp->x);  
50.50            if (1 == *pb)  
51.51            {  
52.52                Console.WriteLine("Your CPU is little endian.");  
53.53            }  
54.54            else if (1 == *(pb + sizeof(int) - 1))  
55.55            {  
56.56                Console.WriteLine("Your CPU is big endian.");  
57.57            }  
58.58            else 
59.59            {  
60.60                Console.WriteLine("Unkown.");  
61.61            }  
62.62        }  
63.63    }  
64.64  
65.65    unsafe struct Point  
66.66    {  
67.67        public int x;  
68.68        public int y;  
69.69    }  
70.70} 
 1using System;
 2
 3namespace Sophy.UnsafeCode
 4{
 5    unsafe class Program
 6    {
 7        static void Main(string[] args)
 8        {
 9            //在栈上分配内存
10            byte* arr_on_stack = stackalloc byte[100];
11
12            //下标访问数组
13            for (int i = 0; i < 100; i++)
14            {
15                arr_on_stack[i] = 0;
16            }
17
18            //在堆上分配内存
19            fixed (byte* arr_on_heap = new byte[100])
20            {
21                //指针访问数组
22                for (int i = 0; i < 100; i++)
23                {
24                    *(arr_on_heap + i) = 0;
25                }
26            }
27
28            //在栈上分配一个结构体
29            Point p = new Point();
30            //用结构体指针操作栈上的结构体
31            Point* pp = &p;
32            pp->x = 200;
33            (*pp).y = 300;
34
35            //在堆上分配一个结构体
36            fixed (byte* bs = new byte[sizeof(Point)])
37            {
38                //用结构体指针操作堆上的结构体
39                Point* ph = (Point*)bs;
40                (*ph).x = 400;
41                ph->y = 500;
42            }
43
44            //打印结构体内存地址
45            Console.WriteLine("pp Memory Address: 0x{0:X}.", ((int)pp).ToString());
46
47            //识别CPU字节序
48            pp->x = 1;
49            byte* pb = (byte*)&(pp->x);
50            if (1 == *pb)
51            {
52                Console.WriteLine("Your CPU is little endian.");
53            }
54            else if (1 == *(pb + sizeof(int) - 1))
55            {
56                Console.WriteLine("Your CPU is big endian.");
57            }
58            else
59            {
60                Console.WriteLine("Unkown.");
61            }
62        }
63    }
64
65    unsafe struct Point
66    {
67        public int x;
68        public int y;
69    }
70}
 
在C#中想要使用指针,要给类型、方法或者代码段加上unsafe关键字,并且编译的时候要加上/unsafe选项。在Visual Studio 2005中,勾上“项目属性->生成”里的“允许不安全代码”,编译时就会自动加上/unsafe选项。
    C#中的指针只能指向值类型,并且值类型中不能含有引用类型。如果允许指针指向引用类型,那将是非常令人迷惑的事情。也许你注意到了这行代码:
     fixed (byte* bs = new byte[sizeof(Point)])
     {
     }
     它把一个数组赋给了一个指针变量,数组是引用类型,那不是和上面说的矛盾了吗?其实我认为是编译器做了特殊处理,在这里直接将数组的地址赋给了指针变量。一个简单的fixed关键字,编译器在背后肯定做了不少事情。因为引用类型是在托管堆中分配的,受运行库管理,当内存中碎片太多时,垃圾回收器可能会启动内存压缩,有可能将数组移动到别的地方,这时指针指向的就不是原来的数组了,所以fixed作用还在于,把引用类型的数组“钉”在内存的那个位置上,不允许垃圾回收器移动,直到代码执行到fixed后面两个大括号之外为止。
 
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yfqvip/archive/2009/09/24/4588254.aspx
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
C#指针操作Marshal实例
C# unsafe code
C# 不安全代码 | 菜鸟教程
Unsafe Code Tutorial (C#)
Shell排序
C# 7.0 新特性4:返回引用
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服