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

本文关键字:工作 asp net 为什么 指针 想知道 | 更新日期: 2023-09-27 18:01:34

我想尝试c#中的指针算术。我使用了一个asp.net web应用程序,期望它不会有问题,如果它是这个或控制台应用程序。

这是我尝试的:

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));
    }
}

结果如下:

0000000000000002,0000000004 b5ca00,1,0000000004 b5c9fc,

我显然希望第二个是第一名。有人明白吗?

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

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

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

Debug.WriteLine("{0:x16}",*(pB - 1));
Debug.WriteLine("{0:x16}",*(pB + 0));    
Debug.WriteLine("{0:x16}",*(pB + 1));

然后你会得到输出

00000badf00dd00d  <-- some pointer value
0000000000000002  <-- contents of b
0000000000000001  <-- contents of a

,你就会知道堆栈的生长方向与你认为的相反。在许多体系结构中,将一些内容压入堆栈会减少堆栈指针。

当然,正如其他人指出的那样,我们不能保证内容如何在堆栈上布局,甚至不能保证内容是否首先进入堆栈;在某些情况下,局部变量可能会被放在堆上,并且其地址永远不会被占用的局部变量可能会被注册。例如,如果不取"a"的地址会发生什么?它最后还会在堆栈上吗?也许不是!

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

对于几乎所有的编程语言来说,局部变量如何在堆栈上布局(或者它们是否在堆栈上)是未指定的。

逻辑局部变量存储的几个问题:

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

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

所以*(pB - 1)b前面的内存解引用的结果为未指定行为。

在。net中,你通常可以在数组中使用指针算术或手动分配内存块。

您的第二个引用是对pB - 1的地址解引用,而不是对pB解引用并减去1。

对于返回值1的第二行,它需要读起来像这样:

Debug.WriteLine("{0:x16}",*(pB) - 1);

我不认为你可以或者应该对。net在内存中的位置做出任何假设。在您的情况下,*pB正确地解析为2,因为这是b的值。我不认为你可以假设a将被分配在b之前,这样*(pB - 1)就指向它了。你看到的是'堆栈上b之前的int '的整数值

当你写:

Debug.WriteLine("{0:x16}",*(pB - 1)); 

你正在取pB - 1的内存位置的值。不是pB - 1的值。

试着用这个:

Debug.WriteLine("{0:x16}",(*(pB) - 1));