C++ G++;编译器在每次运行后返回相同的变量地址(即使在名称更改后)

C++ G++;编译器在每次运行后返回相同的变量地址(即使在名称更改后),c++,visual-c++,g++,compiler-optimization,memory-address,C++,Visual C++,G++,Compiler Optimization,Memory Address,我的假设是编译器在每次运行后都会更改变量的地址。(在MSVC中也是如此) 出于某种原因,每次运行时,我的G++编译器都会返回相同的地址 即使在关闭并再次运行之后,它也会返回已注释的地址。有没有我不知道的优化技术 在更改变量名之后,这将返回相同的地址 想了解MSVC和G++之间的区别及其背后的原因 #include<iostream> using namespace std; int main(){ int b[] = {23,4,6,1,5,7,8,7}; cout &

我的假设是编译器在每次运行后都会更改变量的地址。(在MSVC中也是如此)

出于某种原因,每次运行时,我的G++编译器都会返回相同的地址

  • 即使在关闭并再次运行之后,它也会返回已注释的地址。有没有我不知道的优化技术
  • 在更改变量名之后,这将返回相同的地址
  • 想了解MSVC和G++之间的区别及其背后的原因

    #include<iostream>
    using namespace std;
    
    int main(){
       int b[] = {23,4,6,1,5,7,8,7};
       cout << b; //0x61fef0
       cout << endl;
       cout << &b[0]; //0x61fef0
    
       return 0;
    
    #包括
    使用名称空间std;
    int main(){
    int b[]={23,4,6,1,5,7,8,7};
    
    cout编译器从可用的可用内存池分配内存。计算机通常维护一个可用内存和已用内存的列表。因此,每次编译后,您将获得相同的地址。因此,即使更改变量naem,您也将获得相同的内存地址。

    当编译器编译对象文件时,所有地址都是相对的。lin然后,ker获取所有这些地址并将它们放在正确的位置。所谓正确的位置,我指的是操作系统期望它们位于的位置。(详细信息由依赖于平台的链接器脚本决定)

    加载可执行文件时,操作系统将把代码(ELF中的.text部分)和数据(.data和.bss部分)放在正确的地址,然后转移到这些地址

    在程序分支(goto)中,可执行文件中的地址可以是固定的,也可以是相对的(独立于位置)。如果它们是固定的,通常可执行文件使用相同的地址。如果它们是相对的,操作系统可以将可执行文件加载到任何地址,则必须设置额外的蹦床代码才能正常工作

    对于安全操作系统,请使用地址空间布局随机化(ASLR)。在此模式下,操作系统将随机化加载内容的位置。这使得利用安全漏洞变得更加困难。其具体工作方式取决于平台

    据我所知,x86上的Linux使用固定地址,除非您使用
    -PIE
    (独立于位置的可执行文件)构建分配


    希望这能让您更好地了解正在发生的事情。

    为什么会有这种假设?语言本身并没有太多关于实际内存(地址)的说明假设,这里的约束非常抽象,你不应该真的关心它。虽然C++11在对齐和布局方面有一些扩展,但这是另一个主题。@Secundi,谢谢。但我想了解它背后的差异原因。还有一点是,G++允许我访问内存我无法通过MSVC访问的衣服(受限访问)编译器之间的区别在于,不同的编译器对内存的不同的存储,即使它们产生的目标是相同的主机系统。C++标准很少说明如何将变量组织在内存中——这样编译器就可以自由地进行大部分他们喜欢的操作。不同的编译器所做的工作取决于编译的方式。r开发人员对事情的原因(例如,源代码到可执行代码的映射)。