现在的位置: 首页 > 综合 > 正文

【C#】显示引用类型变量的内存地址(以字符串为例)

2018年04月22日 ⁄ 综合 ⁄ 共 1357字 ⁄ 字号 评论关闭

对于C/OC/C++程序员来说,输出一下所创建对象的内存地址,观察、分析或者单纯处于好奇心,都是很平常的事情。

然而对于将安全放在第一位的C#语言来说,这个“平常事”貌似并不那么直接。

本文在stackoverflow的问答基础上对C#语言显示引用类型内存的地址的方法进行了封装,

并以System.String和StringBuilder两个类为例展示了他们的内存地址变化情况。

博文首发地址:http://blog.csdn.net/duzixi

首先,在工程设置中,勾选“允许不安全代码”

其次,编写源代码如下:

/// <summary>/// Get the memory address of reference type.
/// 获取引用类型的内存地址
/// 
/// Created by duzixi.com 2014.11.27
/// www.lanou3g.com All Rights Reserved
/// </summary>

using System;
using System.Text;
using System.Runtime.InteropServices;

namespace GetMemory
{
	class MainClass
	{			
		public static string getMemory(object o) // 获取引用类型的内存地址方法
		{
			GCHandle h = GCHandle.Alloc(o, GCHandleType.Pinned);
			IntPtr addr = h.AddrOfPinnedObject();
			return "0x" + addr.ToString("X");
		}

		public static void Main (string[] args)
		{
			/// 不可变字符串 System.String
			string str1 = "不可变字符串";
			string str2 = str1;
			string str3 = str1;

			str2 = "新的字符串"; // 当有新的赋值时,开辟新的空间,
			Console.WriteLine (str3); // 不发生改变

			// str2指向新的地址,其它不变
			Console.WriteLine("str1:" + getMemory(str1));
			Console.WriteLine("str2:" + getMemory(str2));
			Console.WriteLine("str3:" + getMemory(str3) + "\n");

			/// 可变字符串 StringBuilder
			StringBuilder txt = new StringBuilder ("可变字符串");
			StringBuilder aTxt = txt;
			StringBuilder bTxt = txt;

			aTxt.Append ("\n 后面追加另一个字符串"); 
			Console.WriteLine (bTxt); // 另一个引用字符串内容随之发生改变

			// 内存地址不变
			Console.WriteLine(" txt:" + getMemory(txt));
			Console.WriteLine("aTxt:" + getMemory(aTxt));
			Console.WriteLine("bTxt:" + getMemory(bTxt));

		}
	}
}


关于神奇的GCHandle以及相关方法还有待进一步研究,不过从运行结果来看这样已经可以说明一些关于内存的问题了。

抱歉!评论已关闭.