堆栈地址增长方向为什么会不同

SpikeKnox 2006-11-01 06:44:35
记得堆栈空间是从高地址向低地址伸展的,可为何我在.Net下编译后的程序地址确是由低向高增长的呢?

测试代码如下:
public static class Test
{
public unsafe static void Main()
{
int x, y;
x = 10;
y = 50;
int* pX, pY,pZ;
pX = &(x);
pY = &(y);
pZ = pX - 1; //pZ想指向y

Console.WriteLine("Address of x: {0:X}",(uint)pX);
Console.WriteLine("Address of y: {0:X}",(uint)pY);
Console.WriteLine(*pZ);

Console.ReadKey();
}

}

调试时的输出:(可以证明堆栈由高地址向低地址伸展)
Address of x: 3C4ECC4
Address of y: 3C4ECC0
50

可运行时的输出却变成了:(由低地址向高地址伸展了?!)
Address of x: 12F45C
Address of y: 12F460
14090491 <-变成了无效值了-_-!
...全文
445 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
SpikeKnox 2006-11-01
  • 打赏
  • 举报
回复
调试时看到的:
x = 10;
00000034 mov dword ptr [ebp-3Ch],0Ah
y = 50;
0000003b mov dword ptr [ebp-40h],32h

EXE文件用ILDASM看:(也是先安排x的值,再是y的值的)
IL_0001: ldc.i4.s 10
IL_0003: stloc.0
IL_0004: ldc.i4.s 50
IL_0006: stloc.1
IL_0007: ldloca.s x
IL_0009: conv.u
IL_000a: stloc.2
IL_000b: ldloca.s y
SpikeKnox 2006-11-01
  • 打赏
  • 举报
回复
按你说的试了,地址是不会变的,

垃圾收集机制我也仔细看过,可这个问题好像与此问题无关,

感觉是编译器在给变量分配内存时,不同的模式下有差异。


还是用 pZ = pX - 1; //pZ想指向y
DEBUG时输出:
Address of x: 3C4ECC4
Address of y: 3C4ECC0
Address of x: 3C4ECC4
Address of y: 3C4ECC0
Value of *pZ: 100

EXE文件输出:
Address of x: 12F45C
Address of y: 12F460
Address of x: 12F45C
Address of y: 12F460
Value of *pZ: 14090574 <- 无效
真相重于对错 2006-11-01
  • 打赏
  • 举报
回复
.net垃圾收集机制,在msdn中只是泛泛而谈,我也没有太深人的了解诸如怎么收集,什么时候改收集,这一切皆是由.net控制,你可以这样测试一下
int* pX = &x;
int* pY = &y;
//第一次输出
Console.WriteLine("Address of x: {0:X}",(uint)pX);
Console.WriteLine("Address of y: {0:X}",(uint)pY);
y =100;
#第二次输出
Console.WriteLine("Address of x: {0:X}",(uint)pX);
Console.WriteLine("Address of y: {0:X}",(uint)pY);
看看两次的输出是否相同

或者用ildasm看看il代码,
SpikeKnox 2006-11-01
  • 打赏
  • 举报
回复
你的意思我有点明白了,用指针指向的值是无效的。
可我就算在程序最后再加一些调用x,y的语句结果也是这样的(那时x,y肯定没有失效)。

但我Main运行过程中的 x 和 y (两个都是值类型的应该在栈上)在内存中的的地址,

如果按栈的正常增长方式,调试中输出的地址可以表明是对的(大->小),
Address of x: 3C4ECC4
Address of y: 3C4ECC0

但在正式的exe文件输出中看到的,分配的变量都是从(小->大)的。
Address of x: 12F45C
Address of y: 12F460
真相重于对错 2006-11-01
  • 打赏
  • 举报
回复
因为那时的x,y,z
可能已经无效了
SpikeKnox 2006-11-01
  • 打赏
  • 举报
回复
谢谢hdt(倦怠)的回答,

但问题是:

调试时用pZ = pX - 1 的输出是对的,但生成的exe中会变成无效值,

要是用pZ = pX + 1 调试时是无效值,生成的exe中的结果是对的。

造成这样的结果,从x和y在内存中的地址来看,就是调试是堆栈中的地址增长是从大到小的,
而编译生成的exe中,看起来堆栈中的地址增长却是从小到大了。
真相重于对错 2006-11-01
  • 打赏
  • 举报
回复
按照你的代码应该是
pZ = pX-1
SpikeKnox 2006-11-01
  • 打赏
  • 举报
回复
y.ToString()显示肯定是对的;
就算Console.WriteLine(y)也可以.

我指的是 pZ指针所指的值,pZ指针要从x值指到y值,指针是应该+1,还是-1.
这句: pZ = pX - 1; //pZ想指向y
真相重于对错 2006-11-01
  • 打赏
  • 举报
回复
因为垃圾收集机制
稍微改一下程序
Console.WriteLine("Address of x: {0:X}",(uint)pX);
Console.WriteLine("Address of y: {0:X}",(uint)pY);
Console.WriteLine(*pZ);

+ Console.WriteLine(y.ToString());
就会相同了

13,190

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 分析与设计
社区管理员
  • 分析与设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧