考虑以下代码
void func(int*list, int length)
{
int temp = 55;
cout<<"&list: "<<&list<<endl;
cout<<"&length: "<<&length<<endl;
cout<<"&temp: "<<&temp;
}
从主要我调用func并给它参数。 为什么我没有得到所有参数相同大小的相邻地址。只有列表和长度在地址中相隔4个字节且相邻。不应该临时相邻。
输出低于但有所不同。
&list: 00D5F8A0
&length: 00D5F8A4
&temp: 00D5F88C //why not 00D5F8A8
答案 0 :(得分:3)
list
和length
是调用者设置此函数参数时创建的堆栈帧的一部分。堆栈帧还包含返回地址,并且可能包含其他信息,具体取决于所涉及的调用约定。
temp
相对于堆栈指针的地址由被调用函数确定,并且可能刚好位于堆栈帧之上......如上所述,它可能不会与论据相邻。
当然,如果你编码得当,你就不必关心它。但是在追踪指针错误时理解这一点很好。
答案 1 :(得分:1)
这些地址都在堆栈内存中。您的程序可能存在于参数和局部变量之间的其他值。堆栈框架的布局因编译器和操作系统而异,但常见的布局可能如下所示:
顶部框架
==================
|功能参数
==================
|退货地址
==================
|基指针
==================
|局部变量
==================
堆叠框架的底部
答案 2 :(得分:1)
你为什么期望它们相邻?
参数通常由调用代码准备。如果它们通过堆栈物理传递,它们通常会有相邻的地址。
另一方面,局部变量通常在调用已经发生时由函数内部管理。
现在,在前者和后者之间,很多事情都会(并且会发生)影响堆栈的状态。例如,调用本身通常会将返回地址存储在堆栈中。该函数的序言代码通常还会将一些家庭数据存储在堆栈中。所有额外数据通常都会嵌入参数值和局部变量之间,因此它们通常不会在内存中直接相邻。
这只是一个场景。该过程的细节非常依赖于实现。参数可以通过寄存器传递,然后(如果需要)由函数本身复制到堆栈存储器。但即使在这种情况下,也不能保证参数和局部变量将被连续存储。
答案 3 :(得分:0)
所有这些变量都存在于分配给进程的内存的堆栈部分中。赋予函数的参数位于stack frame
,而函数中声明的变量存在于function's stack
顶部的process's stack
。