据我所知,当我宣布全局变量int my_var;
时,
它位于<bss>
(未初始化的全局数据)或<.rodata>
(初始化全局数据)部分的固定地址。
EX)
int my_var; // <= It is at <.bss> section
int my_var = 0x1337; // <= It is at <.rodata> section
因此,程序可以使用固定地址找到那些静态值。
问题:但是,我听说位于<stack>
的全局变量。
C运行时启动初始化全局变量:__environ
,program_invocation_name
它们位于<stack>
....这意味着它的地址不固定。
题。程序如何在stack
(非固定区域)中找到全局变量?
__environ等...不在堆栈内;它们是普通的全局变量,它们是指向堆栈内位置的指针(即,值为地址的变量)。初始程序环境,参数等在堆栈中的事实是一个实现细节。它们可以很容易地在堆中分配,或者在其他区域中分配以适应运行时。
唯一重要的是运行时启动和操作系统同意在哪里找到它们。
[回复评论]以下计划应说明:
#include <stdio.h>
extern char **environ;
int main() {
int x;
printf("&envrion = %p\n", &environ);
printf("environ = %p\n", environ);
printf("*environ = %p [%s]\n", *environ, *environ);
printf("&x = %p\n", &x);
return 0;
}
在我的系统上运行时(cc -static x.c; ./a.out),生成:
&envrion = 0x6bbda8
environ = 0x7ffdd6edb3e8
*environ = 0x7ffdd6edb9a2 [CLUTTER_IM_MODULE=xim]
&x = 0x7ffdd6edb2a4
请注意&environ在一个与environ,* environ和&x不同的地址。那是因为后者在堆栈内,而环境本身则不是。
您能提供一本书的示例或参考,指出存储在堆栈中的全局变量吗?
堆栈的重点是根据(时间)变量的范围分配内存,因此将堆栈用于“always-alive”变量是没有意义的(正如您所说,还有另一个部分)目的)。
关于你的例子(int my_var = 0x1337;
),初始化变量可能不会在只读部分上分配,因为它并不意味着它不会在某个时刻被修改(除了编译器的决定)。
题。程序如何在堆栈(非固定区域)中找到全局变量?
堆栈是一个LIFO队列,其中一个指针指示最新位置,每个时态变量获取一个地址(当它在堆栈边界内创建时),指示其位置,直到它被销毁(超出范围)和堆栈指针已更新。但环境变量不存储在堆栈中,它们位于它之上:https://www.thegeekstuff.com/2012/03/linux-processes-memory-layout/