C#内存地址和变量

问题描述 投票:0回答:4

在 C# 中,有没有办法

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

编辑:

int i;
int* pi = &i;
  • 如何打印出 pi 的十六进制值?
c# .net memory-management
4个回答
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();
    }
}

5
投票

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

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

对于数字 2,您使用 & 运算符:

int* p = &myIntVariable;

指针当然必须在不安全的块中完成,并且您必须在项目设置中允许不安全的代码。如果变量是方法中的局部变量,则它会在堆栈上分配,因此它已经是固定的,但如果变量是对象的成员,则必须使用

fixed
关键字将该对象固定在内存中,这样它就不会被固定。被垃圾收集器移动了。


5
投票

最正确地回答您的问题:

#1 是可能的,但有点棘手,并且仅应出于调试原因才进行:

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

这适用于任何对象,并且实际上返回指向内存中对象的内部指针。请记住,由于 GC,地址可能随时发生变化,GC 喜欢在内存中移动对象。

#2 指针不是对象,因此不会从它们继承 ToString。您必须将指针强制转换为 IntPtr,如下所示:

Console.WriteLine((IntPtr)pi);

0
投票

简单回答

static void Main(string[] args)
    {
        unsafe
        {
            int a = 10; 
            int b = 20; 
            int* aPtr = &a;
            int* bPtr = &b;
    
            Console.WriteLine($"Address of a: {(int)aPtr}");
            Console.WriteLine($"Address of b: {(int)bPtr}");
        }
        Console.Read();
    }

详细说明可以在这里找到 链接:https://youtu.be/OPzUnlDBB_I?feature=shared

© www.soinside.com 2019 - 2024. All rights reserved.