您的位置:程序门 -> .net技术 -> c#



关于堆栈的问题?


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


关于堆栈的问题?
发表于:2007-03-06 20:49:07 楼主
c#高级编程(第四版)中第7章总关于堆栈的机制说
堆栈是由上向下填充的,即由高位地址向低位地址填充的。
例如
{
  int   i   =   10   ;  
  double   d   =   30.0
}
如果当前堆栈指针指向的堆栈保留的内存快末尾的地址为800000,则会将i放在存储单元799996   -   799999中,并且值为10.然后再将d放在   799988   -799995的存储单元上。

但是我觉得实际上不是这样的的
例如
class   test
{
      static   void   main()
      {
          int   number   =   1;
          int   number2   =   2;
          unsafe
          {
          system.console.writeline( "number   address   {0} ",   (long)&number);
          system.console.writeline( "number2   address   {0} ",   (long)&number2);

          }
}
}
实际上输出的结果是number2的地址大于number.也就是说实际上是由低位向高位填充的。
到底是c#高级编程(第四版)的说法有错误,还是我的理解有错位,相关的内容我在msdn中没有找到明确的说明,所有只能向大家请教了!


发表于:2007-03-06 20:52:461楼 得分:0
从低位到高位填充.仅限于栈.
发表于:2007-03-06 21:27:542楼 得分:0
to   sunrobust(咸鱼):

那么就是说c#高级编程(第四版)的说法有错误啦!
发表于:2007-03-06 22:48:333楼 得分:0
很奇怪
  class   classconvert
        {
                unsafe   static   void   main()
                {
                        int   number   =   1024;
                        int   number2   =   2;
                        int   number3   =   5;
                        system.console.writeline( "number     address   {0} ",   (long)&number);
                        system.console.writeline( "number2   address   {0} ",   (long)&number2);
                        system.console.writeline( "number3   address   {0} ",   (long)&number3);
                }
        }
在我的机器结果为
number     address   1242228
number2     address   1242224
number3     address   1242220

是按照由高向低的方式入堆栈的,但是屏蔽了number3的代码结果就倒过来了。
class   classconvert
        {
                unsafe   static   void   main()
                {
                        int   number   =   1024;
                        int   number2   =   2;                      
                        system.console.writeline( "number     address   {0} ",   (long)&number);
                        system.console.writeline( "number2   address   {0} ",   (long)&number2);
                       
                }
        }

在我的机器结果为
number     address   1242228
number2     address   1242232

按照由低向高的顺序入堆栈!!!
这是怎么回事呀!


发表于:2007-03-07 08:59:374楼 得分:0
帮lz顶
发表于:2007-03-07 09:16:215楼 得分:0
在线请教!
发表于:2007-03-07 09:23:236楼 得分:0
又不搞c++,觉得关心这个用处不太大.

如果对这个关心的话,可以用c++来编程了.
发表于:2007-03-07 09:23:587楼 得分:0
纠正一下,确实是从高位到低位,各种资料上都是这么说的.关于楼主说的,我再想想.
发表于:2007-03-07 09:24:178楼 得分:0
回头再来,顶lz
发表于:2007-03-07 09:56:059楼 得分:0
栈:在windows下,   栈是向低地址扩展的数据结构,是一块连续的内存的区域。
发表于:2007-03-07 10:11:1810楼 得分:0
mark
发表于:2007-03-07 11:07:5311楼 得分:0
根本的原因就是:
int   number1,number2根本不在堆,
内建数据类型的局部变量(local)在栈中
在.net的内存模型下,只有托管的内存才放在托管堆里,有虚拟机负责分配和释放
发表于:2007-03-07 11:35:1812楼 得分:0
对呀   int   number,number1,number   应该都是放在栈里的,
可是实际的运行结果,有时候是按高到低位入栈,有时候是由低到高位入栈。
不知道我写的那两段代码有什么本质的区别。
发表于:2007-03-07 12:41:4713楼 得分:0
lz,
在理论上栈确实是向下增长,
当局部变量多于两个的时候确实是向上增长,
当局部变量为3,4,5多个时,就是正常情况
这个应该是算唯一的一个特例吧,具体原因不详,我想可能是微软为了优化framework
发表于:2007-03-07 12:51:3114楼 得分:0
int   number   =   1;
int   number2   =   2;

int分配内存是随机的,哪有空闲内存就分到哪,在这本书里也讲到了。
试一下
struct
{
int   number   =   1;
int   number2   =   2;
}
发表于:2007-03-07 12:56:2115楼 得分:0
学习
发表于:2007-03-07 14:12:1016楼 得分:0
1   分配的顺序取决于在   il   中的分配顺序而不是   c#里面的顺序。

csc在把c#代码变成il代码时“不一定”按顺序(通过layout指定,默认情况下class不按顺序struct按顺序,可以修改)

所以你分析这些问题应该用il来分析而不是c#代码。


2   堆     和       栈           是完全不同的数据结构,   而书里写   “堆栈”的,最好看看英文原本是写stact   还是   heap  

发表于:2007-03-07 14:15:2417楼 得分:0
stack   不是stact,手误
发表于:2007-03-07 14:44:2918楼 得分:0
up
发表于:2007-03-07 15:00:2319楼 得分:0
堆是堆

栈是栈

都是大学课程祸害人啊.全叫堆栈
发表于:2007-03-07 15:03:0820楼 得分:0


简单的说:

你所有new的东西,都在堆里面


你的变量,递归临时生成的东西,都在栈里面


大学课程倒是轻松     ,一个 "堆栈 "全解决了
发表于:2007-03-07 15:03:3421楼 得分:0
帮顶!
发表于:2007-03-07 15:40:2422楼 得分:0
大学里讲的是数据结构的软件模拟堆栈,堆栈就是堆栈
而在系统结构和操作系统的系统级编程里堆是stack,栈是heap
好好回忆一下老师上课讲的吧
发表于:2007-03-07 16:59:2223楼 得分:0
我做了实验,并没有出现楼主那种情况,一切都是正常的,从高位到低位,楼上诸位的意思是楼主连堆和栈都没弄懂。我想是误会了,关于堆和栈的区别如果没弄清楚也不会问这种问题。如果说msil不按顺序,那是有可能的。
顺便问一下,c#中调用函数时的压栈顺序是什么样?相当于c中的_stdcall还是_cdecl?msil里看不出来.......学c#才2个月,很多东西感觉都不太明了-_-!。
        class   program
        {
         
                unsafe   static   void   main(string[]   args)
                {
                        int   a   =   1024;
                        int   b   =   15;
  //                       int   c   =   16;
                        console.writeline( "address   a:{0} ",   (int)&a);
                        console.writeline( "address   b:{0} ",   (int)&b);
  //                       console.writeline( "address   c:{0} ",   (int)&c);
                }
        }
发表于:2007-03-07 17:07:0724楼 得分:0
引用楼上的话:堆是堆,栈是栈.
值类型本来是放在栈中,不过你既然都拿他去cosole了,肯定就装箱放堆里了.
兄弟,装箱操作你没看透啊.
发表于:2007-03-07 17:19:3625楼 得分:0
装箱的是变量的地址而不是变量的本身,变量地址的值装不装箱与我何干,我要的是变量地址的值。
发表于:2007-03-07 17:22:0526楼 得分:0
经测试,没问题啊!
发表于:2007-03-07 17:45:3027楼 得分:0
发表于:2007-03-07 17:54:2828楼 得分:0
为什么有人测试正常,
有的人测试两种增长方向?
我用的是.net2.0,winxp   测试结果是2个变量时向上增长,3个向下增长
发表于:2007-03-07 19:11:2629楼 得分:0
这个可能与编译器有关!不同的编译器有不同的结果吧
发表于:2007-03-07 22:24:2530楼 得分:0
我用的是   net2.0,win2003
发表于:2007-03-09 16:30:0631楼 得分:0
to:fortner
抱歉,兄弟,看错了哈。
沉默中,为我的草率道歉!
学习ing


快速检索

最新资讯
热门点击