c#中在堆栈中内存分配是向下填充的,即由高内存地址向低内存地址分配,为了证明这个问题,写代码如下:
class Program
    {
        static unsafe void Main(string[] args)
        {
            int x = 1;
            int y = 2;
            double z = 3.6;
            Console.WriteLine("Address of x " + (uint)&x);
            Console.WriteLine("Address of y " + (long)(&y));
            Console.WriteLine("Address of z " + (long)(&z));        }
    }
显示结果是:
Address of x 1242224
Address of y 1242220
Address of z 1242212
说明内存由高到低分配。如果代码如下(即删掉变量z的声明):
class Program
    {
        static unsafe void Main(string[] args)
        {
            int x = 1;
            int y = 2;
            Console.WriteLine("Address of x " + (uint)&x);
            Console.WriteLine("Address of y " + (long)(&y));
        }
    }
显示结果是:
Address of x 1242228
Address of y 1242232
内存好像是由低到高分配。再次重写代码如下(即改变变量y的类型):
class Program
    {
        static unsafe void Main(string[] args)
        {
            int x = 1;
            double y = 2.2;
            double z = 3.6;
            Console.WriteLine("Address of x " + (uint)&x);
            Console.WriteLine("Address of y " + (long)(&y));
            Console.WriteLine("Address of z " + (long)(&z));        }
    }
显示结果是:
Address of x 1242212
Address of y 1242216
Address of z 1242224
内存好像也是由低到高分配。上述现象怎么解释?

解决方案 »

  1.   

    1、我这测试没有你说的现象,都是从高到低
    2、long在.net下为64位,
    3、反汇编后代码
      int x = 1;
    00000000  push        ebp  
    00000001  mov         ebp,esp 
    00000003  sub         esp,14h 
    00000006  push        edi  
    00000007  push        esi  
    00000008  mov         dword ptr [ebp-4],1 
    double  y = 2;
    0000000f  mov         dword ptr [ebp-0Ch],0 
    00000016  mov         dword ptr [ebp-8],40000000h 
    double z = 3.6;
    0000001d  mov         dword ptr [ebp-14h],0CCCCCCCDh 
    00000024  mov         dword ptr [ebp-10h],400CCCCCh
      

  2.   

    堆栈是由高到低分配的
    我在.net 2.0下测试 没出现你这样的情况。
    把这个语句
    Console.WriteLine("Address of y " + (long)(&y));
    改成
    Console.WriteLine("Address of y " + (long)&y);
    试试`
      

  3.   

    hdt(倦怠) ( ) 信誉:120    Blog  2007-01-08 18:34:09  得分: 0  
     
     
       1、我这测试没有你说的现象,都是从高到低
    2、long在.net下为64位,
    3、反汇编后代码
      int x = 1;
    00000000  push        ebp  
    00000001  mov         ebp,esp 
    00000003  sub         esp,14h 
    00000006  push        edi  
    00000007  push        esi  
    00000008  mov         dword ptr [ebp-4],1 
    double  y = 2;
    0000000f  mov         dword ptr [ebp-0Ch],0 
    00000016  mov         dword ptr [ebp-8],40000000h 
    double z = 3.6;
    0000001d  mov         dword ptr [ebp-14h],0CCCCCCCDh 
    00000024  mov         dword ptr [ebp-10h],400CCCCCh
      
     ---------------------------------------------------------
    请问这么纯的反汇编代码是用哪个东西反出来的?? 我在IDA下反的都是IL..讨厌死了
      

  4.   

    内存分配是clr控制的,clr会根据系统的情况来决定如何分配。并不一定由低到高。
      

  5.   

    第一段代码是没有问题的,地址是从高到低分配的。
    第二、三段代码内存分配是从低到高的,不符合从高到低分配的原则。
    我用的是vs.net2005。
      

  6.   

    内存的分配是随机的,分配的时候先找没有被占用内存然后再具体分配,这和地址高低没有关系吧
    ------堆的内存分配才是随机的,堆栈就是顺序分配的。内存分配是clr控制的,clr会根据系统的情况来决定如何分配。并不一定由低到高。
    -----只有堆的内存才受托管,而栈的内存是不受clr托管的,栈的表现和在非托管程序里的表现是一样的。第二、三段代码内存分配是从低到高的,不符合从高到低分配的原则。
    ------永远都是从高地址向低地址分配,你贴的代码说明不了任何问题,因为你不知道编译器是首先为哪个变量分配内存。有可能先声明的变量后分配内存。但不管怎么样,局部变量的地址肯定是要高于函数实参的地址。
      

  7.   

    内存分配是clr控制的,clr会根据系统的情况来决定如何分配。并不一定由低到高。
    -----只有堆的内存才受托管,而栈的内存是不受clr托管的,栈的表现和在非托管程序里的表现是一样的。========================
         那值类型岂不受托管了?GC如何回收?
      

  8.   

    请lz改成debug模式下再编译看看结果。
    C#里怎么也开始讨论这种问题了。