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
内存好像也是由低到高分配。上述现象怎么解释?
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
内存好像也是由低到高分配。上述现象怎么解释?
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
我在.net 2.0下测试 没出现你这样的情况。
把这个语句
Console.WriteLine("Address of y " + (long)(&y));
改成
Console.WriteLine("Address of y " + (long)&y);
试试`
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..讨厌死了
第二、三段代码内存分配是从低到高的,不符合从高到低分配的原则。
我用的是vs.net2005。
------堆的内存分配才是随机的,堆栈就是顺序分配的。内存分配是clr控制的,clr会根据系统的情况来决定如何分配。并不一定由低到高。
-----只有堆的内存才受托管,而栈的内存是不受clr托管的,栈的表现和在非托管程序里的表现是一样的。第二、三段代码内存分配是从低到高的,不符合从高到低分配的原则。
------永远都是从高地址向低地址分配,你贴的代码说明不了任何问题,因为你不知道编译器是首先为哪个变量分配内存。有可能先声明的变量后分配内存。但不管怎么样,局部变量的地址肯定是要高于函数实参的地址。
-----只有堆的内存才受托管,而栈的内存是不受clr托管的,栈的表现和在非托管程序里的表现是一样的。========================
那值类型岂不受托管了?GC如何回收?
C#里怎么也开始讨论这种问题了。