C中指针和全局变量的位置

指针全局变量存储在C中的哪里? 它们是保存在内存,堆还是堆栈中?

全局变量可以在几个地方,具体取决于它们的设置方式 – 例如, const全局变量可能位于可执行文件的只读部分。 “普通”全局变量位于可执行文件的读写部分。 它们根本不在堆或堆栈上。 指针只是一种变量,所以它们可以是你想要它们的地方(如果你是malloc()它们在堆上,如果它们是局部变量则在堆栈上,或者如果它们是全局变量则在数据部分中) 。

编译文件时,在“编译单元”(粗略地说,“c文件”)中定义的具有“程序持续时间”(静态或全局变量)的变量确定该程序需要多少全局空间,以及它如何已初始化。

链接

当链接器创建可执行文件时,它会将此信息组合在一起,并将其放入用于此目的的可执行文件的各个部分中。 然后,链接器会遍历并更改对该数据的所有引用,以便在加载程序时将该数据放入进程的内存空间。 所以指向全局数据的指针就像源文件中的常量一样; 不需要为他们留出任何记忆。

对于零初始化或未初始化的全局数据,仅存储此类数据所需的空间量。 对于初始化数据,存储初始值。

加载

加载程序时,加载程序将查看程序文件以告知零初始化数据需要多少,并为其预留足够的进程内存空间,并将其全部初始化为二进制零。 对于初始化数据,它为此留出内存并将其初始化为保存在exe文件中的初始值。 它还为堆(由malloc()使用)和堆栈预留了区域。

动态库

如果您的代码位于动态库中,则链接器无法知道它将放置全局数据的位置。 在这种情况下,它在库中创建部分以告诉它对全局数据的引用的位置,并且加载器负责在加载文件时将引用更改为指向正确的位置(这就是为什么你传递-fPIC在dcc的gcc命令行上)。 但由于这是在加载时完成的,所以当程序运行时,数据的放置是已知的,因此加载器知道数据指向全局数据的指针仍然可以作为程序中的常量。

动态加载

如果你动态链接到一个DLL,加载器不知道它,所以你必须调用知道如何加载DLL并获取其导出的数据和函数的地址的函数。

全局变量通常存储在应用程序的数据段中。

指针的存储方式与其他变量的存储方式不同(例如,如果您有一个int*类型的局部变量,它将存储在堆栈中,与任何其他局部变量相同)。

malloc(),calloc()或realloc()所做的所有分配都存储在堆上,而所有局部变量都存储在堆栈中。

所有全局变量和静态变量都存储在数据段中,而常量则存储在代码段中。

通过malloc()内存是从堆中获取的。 这提供了指向内存的指针。

更多信息在这里 。