代码之家  ›  专栏  ›  技术社区  ›  Ray Lu

C#内存地址和变量

  •  23
  • Ray Lu  · 技术社区  · 17 年前

    在C#中,有没有办法

    1. 获取存储在内存中的内存地址 引用类型变量?
    2. 获取一个文件的内存地址 变量

    编辑:

    int i;
    int* pi = &i;
    
    • 如何打印pi的十六进制值?
    3 回复  |  直到 17 年前
        1
  •  14
  •   Jeffrey Hantin    17 年前

    对于#2而言 & 运算符将以与C中相同的方式工作。如果变量不在堆栈上,则可能需要使用 fixed 语句,以便在您工作时将其固定下来,以便垃圾收集器不会移动它。

    对于#1,引用类型更为棘手:您需要使用 GCHandle ,并且引用类型必须是可blittable,即具有已定义的内存布局并可按位复制。

    IntPtr (定义为与指针大小相同的整数类型),并从那里开始 uint ulong (取决于基础计算机的指针大小)。

    using System;
    using System.Runtime.InteropServices;
    
    [StructLayout(LayoutKind.Sequential)]
    class Blittable
    {
        int x;
    }
    
    class Program
    {
        public static unsafe void Main()
        {
            int i;
            object o = new Blittable();
            int* ptr = &i;
            IntPtr addr = (IntPtr)ptr;
    
            Console.WriteLine(addr.ToString("x"));
    
            GCHandle h = GCHandle.Alloc(o, GCHandleType.Pinned);
            addr = h.AddrOfPinnedObject();
            Console.WriteLine(addr.ToString("x"));
    
            h.Free();
        }
    }
    
        2
  •  5
  •   Guffa    17 年前

    数字1根本不可能,您不能有指向托管对象的指针。但是,您可以使用IntPtr结构来获取有关引用中指针地址的信息:

    GCHandle handle = GCHandle.Alloc(str, GCHandleType.Pinned);
    IntPtr pointer = GCHandle.ToIntPtr(handle);
    string pointerDisplay = pointer.ToString();
    handle.Free();
    

    int* p = &myIntVariable;
    

    当然,指针必须在不安全的块中执行,并且必须允许在项目设置中使用不安全的代码。如果变量是方法中的局部变量,则会在堆栈上分配该变量,因此该变量已经固定,但如果变量是对象的成员,则必须使用 fixed 关键字,这样它就不会被垃圾收集器移动。

        3
  •  4
  •   IS4    10 年前

    object o = new object();
    TypedReference tr = __makeref(o);
    IntPtr ptr = **(IntPtr**)(&tr);
    

    这适用于任何对象,并实际返回指向内存中对象的内部指针。记住,由于GC喜欢在内存中移动对象,所以地址随时都可能更改。

    #2个指针不是对象,因此不会继承 托斯特林 从他们那里。您必须将指针投射到 像这样:

    Console.WriteLine((IntPtr)pi);
    
    推荐文章