想知道为什么指针算法不能在asp.net中工作

the*_*law 2 c# math pointers

我想在c#中尝试指针运算.我使用了一个asp.net网络应用程序,期望它是无论是这个还是一个控制台应用程序.

这是我试过的:

public class memorytest
{
    public class Sample
    {
        public int A;
        public int B;
        public int C;
        public int D;
    }

   public static unsafe void Main()
   {
    Sample s = new Sample {A = 1, B = 2, C = 3, D = 4};
    int a = 1;
    int b = 2;
    int* pA = &a;
    int* pB = &b;
    Debug.WriteLine("{0:x16}",* pB);
    Debug.WriteLine("{0:x16}",*(pB - 1));
    Debug.WriteLine(*pA);
    Debug.WriteLine("{0:x16}",*(pB - 2));
    }

}
Run Code Online (Sandbox Code Playgroud)

结果是这样的:

0000000000000002,0000000004b5ca00,10000004b5c9fc,

我显然希望第二个是数字1.有人理解这一点吗?

Eri*_*ert 10

首先,如果你想了解堆栈是如何布局的,那么启动调试器并查看调试器中的堆栈似乎要容易得多.

假设由于某种原因你想继续编写程序来检查自己的堆栈状态:你过早地停止了试验.你应该写的程序是:

Debug.WriteLine("{0:x16}",*(pB - 1));
Debug.WriteLine("{0:x16}",*(pB + 0));    
Debug.WriteLine("{0:x16}",*(pB + 1));
Run Code Online (Sandbox Code Playgroud)

然后你会得到输出

00000badf00dd00d  <-- some pointer value
0000000000000002  <-- contents of b
0000000000000001  <-- contents of a
Run Code Online (Sandbox Code Playgroud)

而你会发现堆栈的生长方向与你认为的相反.在许多架构中,将某些东西推入堆栈会减少堆栈指针.

当然,正如其他人所指出的那样,我们不保证堆栈上的东西是如何布置的,或者即使东西首先进入堆栈也是如此; 在某些情况下,局部变量可以放在堆上,并且可以注册其地址永远不会被占用的局部变量.例如,如果你不采用"a"的地址会发生什么?它是否仍然在堆栈中?也许不吧!


Cod*_*aos 6

这个问题与ASP.net无关.你使用指针算术是完全错误的.

局部变量如何在堆栈上布局(或者如果它们甚至在堆栈上)几乎都没有指定任何编程语言.

存储逻辑局部变量的一些复杂情况:

  • 大多数编译器会将局部变量放在寄存器中,除非你得到它们的地址.
  • 由lambda绑定的变量,或async方法中的变量都在堆对象上.
  • 即使它们确实在堆栈上,顺序也是任意的.
  • 逻辑变量和存储器位置之间甚至没有1对1的对应关系.一旦变量超出范围,就可以重用内存位置.

指针运算通常只能在单个分配的内存块中使用.

因此*(pB - 1),取消引用前面的内存的结果b是未指定的行为.

在.net中,您通常可以在数组内部使用指针算法或手动分配内存块.