我正在发布一个代码。
using System;
using System.Runtime.InteropServices;
class TestPointer
{
public static void Main(string[] args)
{
if (args.Length == 0)
{
unsafe
{
int t = 8;
int* p = &t;
IntPtr addr = (IntPtr)p;
Console.WriteLine(addr.ToString("x"));
Console.WriteLine("before: " +(*p));
Console.ReadLine();
Console.WriteLine("after: " + (*p));
}
}
else
{
unsafe
{
string str = args[0];
GCHandle handle = GCHandle.Alloc(str, GCHandleType.Pinned);
IntPtr pointer = GCHandle.ToIntPtr(handle);
int* p = (int*)pointer;
int t = 5;
p = &t;
Console.WriteLine((*p));
}
}
}
}
我已在两个实例中运行此代码。
在instance1中我调用了TestPointer.exe,实例1显示内存位置为8,而执行停止在Console.ReadLine()语句中。在下一步中,我运行另一个实例(instance2)与TestPointer.exe 12f470(实例1中显示的内存地址),所以在这种情况下,我将值从8更改为5,并在read1之后从instance1更改 应该显示值5,但它仍然显示8.原因是什么?
答案 0 :(得分:1)
这两个进程有两个不同的虚拟地址空间。如果一个进程可以在没有明确执行某种共享(内存映射文件等)的情况下踩踏另一个进程中的值,我会感到非常恐惧。
这是一项教育活动,还是你想要实现的目标,这只是一次初步尝试?如果是后者,请向我们提供有关您正在尝试做的更多详细信息。
答案 1 :(得分:1)
嗯,首先,实例之间的内存是隔离的。在MS-DOS时代,情况并非如此,但如今,它是每个现代操作系统的“主要指令”。
因此,您永远无法以这种方式跨实例传递数据。
另一方面,内存分配器并不保证一旦调用它就会在同一个地方分配内存 - 远离它。我的建议是远离硬编码的地址。
这里有点透视......看起来你需要学习很多关于操作系统,CLR和内存管理的基础知识。对我来说,这意味着你不应该触及“不安全”的结构。你正在玩火。它是一种高级构造,主要用于与旧代码库的互操作性。我的建议是远离它。
答案 2 :(得分:0)
原因是您无法轻易访问其他进程的内存。 这就是所谓的“虚拟内存”,它是现代操作系统保护运行进程内存免受损坏的方式。