【问题标题】:Is the final memory address of declared functions in any programming language (C++, C#, Java, C...) relative or absolute?任何编程语言(C++、C#、Java、C...)中声明的函数的最终内存地址是相对的还是绝对的?
【发布时间】:2012-03-15 12:22:25
【问题描述】:

任何编程语言(C++、C#、Java、C...)中声明函数的最终内存地址是相对的还是绝对的? (我不是问机器码语言的寻址方式是相对还是绝对)

(我会说这是相对的,但我需要专家来评论) 如果是相对的,这意味着无论我们在哪里调用函数,都会根据程序计数器的位置将函数复制并放入堆栈。因此,两个线程同时调用同一个函数,如果它们不共享同一个变量,它们不会相互影响。

如果是绝对的,这意味着两个线程调用同一个函数,它们会进入同一个地址!!(是静态还是非静态函数)另外,每次我们创建一个类对象,一定的大小每个对象的可用于存储方法(函数)。那么它会让一个物体的尺寸变得非常大!

【问题讨论】:

    标签: c++ multithreading function callstack


    【解决方案1】:

    你错了。

    主可执行文件中函数的虚拟内存地址是绝对的,物理内存地址甚至可以在函数运行时改变(如果操作系统换出进程)。

    对于库,虚拟地址可以是绝对的或相对的。如果是相对的,则称为“位置无关代码”,如果库无法在其首选地址加载,则很有用。

    代码没有放在堆栈上。本地(自动持续时间)变量通常是,这意味着并发和递归/重入调用的单独副本。由于代码是只读的,因此多个线程访问同一个地址是没有问题的。

    JITted 语言在运行时确定每个函数的地址,在从中间语言(如 Java 字节码)到机器代码的转换过程中。

    函数也不存储在对象中。通常,一个对象有一个指向函数指针数组的指针,以支持多态性(这称为虚函数)。这些函数指针是相对于对象访问的,但最终的代码地址是绝对的(同样,只有虚拟地址)。

    如果函数被内联,那么它可能只是作为混入其他函数的片段而存在。

    【讨论】:

    • 我可以说代码只是告诉处理器下一步做什么的指令。如果两个线程调用相同的函数并传递具有相同地址的变量,那么它可能会变得不安全。我正确吗?我错了。只有参数和局部变量会被放入堆栈。我说的对吗?
    • @WooD:使用相同地址的两个线程是否不安全取决于它们是写入该地址还是简单地从该地址读取。并发阅读是完全安全的,根本不需要任何同步。您的其余评论是正确的。
    【解决方案2】:

    对于 Java 编程语言,您不能在运行时修改函数的字节码(尽管您可以动态创建和加载新类)。在许多现代机器上,您不能同时执行和修改内存中的同一位置,因此这也是不可能的。即使操作系统允许这样做,也没有正常的代码会这样做。

    局部变量通常存储在堆栈中,而不是与函数指令一起存储。对于 C 中的静态局部变量,它们将存储在全局程序文本中,同样不会与函数一起存储。

    【讨论】:

    • 一个内存区域是否可以执行和修改取决于虚拟内存映射表中的权限。
    猜你喜欢
    • 1970-01-01
    • 2014-03-25
    • 1970-01-01
    • 1970-01-01
    • 2018-10-22
    • 1970-01-01
    • 1970-01-01
    • 2013-05-10
    • 2011-09-04
    相关资源
    最近更新 更多