连续声明的变量的内存地址顺序总是降序吗?
Posted
技术标签:
【中文标题】连续声明的变量的内存地址顺序总是降序吗?【英文标题】:Is the order of memory addresses of successively declared variables always descending? 【发布时间】:2012-09-08 10:15:09 【问题描述】:为什么返回的指针地址的十六进制值总是按降序排列?
例如这里int a
是在int d
之前声明的,所以它的地址总是大于d
,对于&b
,&e
和&c
,&f
,我想知道这是一个固定的行为还是这个编译器依赖?
我正在使用gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-1
)
#include<stdio.h>
int main(void)
int a=1;
int d=1;
char b='a' ;
char e='a';
float c=1.0;
float f=1.0;
printf("a=%p\nd=%p\nb=%p\ne=%p\nc=%p\nf=%p\n",&a,&d,&b,&e,&c,&f);
if (&a>&d)
printf("&a>&d\n");
else
printf("&a<&d");
if (&a>&d && &b>&e && &c>&f)
printf("addresses are in descending order");
else
printf("false");
return 0;
输出:
a=0xbfc6bd98 //a>d
d=0xbfc6bd94
b=0xbfc6bd9f //b>e
e=0xbfc6bd9e
c=0xbfc6bd90 //c>f
f=0xbfc6bd8c
&a>&d
addresses are in descending order
PS:我是c新手
【问题讨论】:
地址不分配给变量,但值存储在内存地址中。 @moooeeeep 我的意思是一样的,只是没有使用正确的词。:) @AshwiniChaudhary - 你需要参加更好的测验。通常会收到有关地理、历史和我的仇恨电影和电视的问题。 (我通常在电影院里睡着了!) 【参考方案1】:在Smashing The Stack For Fun And Profit, by Aleph One 中找到了很好的解释。 提取了最相关的部分。
/------------------\ lower | | memory | Text | addresses | | |------------------| | (Initialized) | | Data | | (Uninitialized) | |------------------| | | | Stack | higher | | memory \------------------/ addresses Fig. 1 Process Memory Regions
[...]
The stack consists of logical stack frames that are pushed when calling a function and popped when returning. A stack frame contains the parameters to a function, its local variables, and the data necessary to recover the previous stack frame, including the value of the instruction pointer at the time of the function call. Depending on the implementation the stack will either grow down (towards lower memory addresses), or up. In our examples we'll use a stack that grows down. This is the way the stack grows on many computers including the Intel, Motorola, SPARC and MIPS processors.
[...]
Let us see what the stack looks like in a simple example: example1.c: ------------------------------------------------------------------------------ void function(int a, int b, int c) char buffer1[5]; char buffer2[10]; void main() function(1,2,3); ------------------------------------------------------------------------------
[...]
With that in mind our stack looks like this when function() is called (each space represents a byte): bottom of top of memory memory buffer2 buffer1 sfp ret a b c <------ [ ][ ][ ][ ][ ][ ][ ] top of bottom of stack stack
如您所见,新的(局部)变量被压入堆栈顶部。根据架构的设计,堆栈会向更高的内存地址或更低的内存地址增长,在您的情况下是后者。
从 C 语言规范的角度来看,随后分配的变量的内存位置顺序是未指定的。因此,这取决于...
【讨论】:
【参考方案2】:您不能对此做出任何假设。使用 some 编译器、some 架构和 some 编译器开关,您可能会看到这些行为,即局部变量被分配在连续降低堆栈地址,但优化和其他因素可以改变这种行为。
【讨论】:
额外的挑剔:C 中没有堆栈。大多数实现使用堆栈。 理论上,实现甚至可以使用一些巧妙的地址随机化技术来分配自动变量。或者它可以选择重新排序变量以最小化对齐需求。或者它可以为浮点数和整数使用单独的位置。一切顺利... @wildplasser: 或者它可以优化一些变量(当然,前提是你不获取他们的地址)【参考方案3】:您要比较其地址的变量都是分配在堆栈上的局部变量。现在堆栈增长的方式(向上或向下)取决于架构。看起来在您的情况下,堆栈正在向下增长,因此您看到的地址正在减少。
【讨论】:
【参考方案4】:很多 ABI 定义了一个向下增长的堆栈。
【讨论】:
【参考方案5】:粗略和半准确的解释(忽略有关堆栈和堆差异的详细信息)是:您希望最小化内存中静态分配的内容与您需要动态分配的内容的冲突。当你的程序运行时,动态的东西通常会变大。为了最大化分配动态内容的容量,静态内容和动态内容通常分配在内存空间的两端,动态内容向静态内容增长。在您的特定情况下,您的编译器看起来像在内存中加载静态内容并从内存的末尾向内存的开头(在静态内容的方向)增长动态内容。
【讨论】:
以上是关于连续声明的变量的内存地址顺序总是降序吗?的主要内容,如果未能解决你的问题,请参考以下文章