如何分配内存寄存器的名称?

时间:2014-04-28 00:54:29

标签: c++ memory

我已经在Matlab编写了相当多的研究生级数值分析课程和统计模拟,但我现在正在尝试学习更通用的语言。我正在使用Lippman的“C ++ Primer”自学C ++。在完成关于指针的部分时,我遇到了让我感到困惑的事情。我编译并运行了以下代码:

#include <iostream>

int main() {
  int ival = 42;
  int *p = &ival;

  std::cout << p << std::endl;
}

我打算为此提供ival所在的内存地址,它似乎有效。这是输出:

$ g++ pointer.cpp -o pointer 
$ ./pointer 
0x7fff5fbffa7c

这让我困惑了几个原因。

1)这是一个12位十六进制数字。这似乎暗示存在至少16 ^ 12(= 2 ^ 48)位(或字节)的可用存储。但是,我安装了4 GB的DDR3 RAM,所以我应该只有4 * 2 ^ 30 Bytes = 32 * 2 ^ 30 Bits = 2 ^ 35 Bits of storage available。所以,我的问题是:这个地址实际上是在RAM中,还是在处理器的Cache中?如果它在RAM中,RAM中如何标记存储器寄存器?或者,我完全不合适?在我的RAM中,似乎不可能存在与每12位十六进制数相对应的存储器寄存器(如果最左边的数字保持不变,则甚至是11位数)。

2)每次运行程序时,ival都存储在完全相同的位置。如果我重命名变量并更改其值,则仍然如此。如果创建第二个变量kval,它的位置是:

0x7fff5fbffa78

距离ival的位置4个字节。 (我现在假设地址以字节标记,因为int使用4个字节。)C ++编译器在构建程序时是否总是以相同的内存地址开始?

我正在使用MacBook Pro,配备4GB的DDR3内存和6 MB的L2缓存(我知道,它是一台已有5年历史的机器),并且正在使用g ++编译器。我希望最终能够学会装配以真正理解这些东西是如何工作的,这就是我为什么要深入研究它的原因。

我试图在Google和Stack Overflow上找到这些信息,但没有任何运气。另外,据我所知,在我正在编写的C ++书中没有解决这个问题。

提前感谢您的时间,如果有任何其他信息有用,请告诉我。

3 个答案:

答案 0 :(得分:2)

  1. 您的操作系统实施virtual memory。内存不是连续分配的,因此您的指针确实指向有效内存(从您的进程的角度来看)。

  2. C ++编译器可能会将变量放在类似程序的类似位置。但是,它不仅取决于编译器,操作系统也会对此产生影响(例如,使用ASLR)。

答案 1 :(得分:2)

两个字 - 虚拟内存。您在代码中使用的内存地址不是物理内存地址,它们是操作系统映射到后台物理内存地址的虚拟内存地址。这允许OS允许不同的进程在内部使用相同的存储器地址但是使它们在物理上彼此隔离,将每个进程的虚拟存储器池映射到物理存储器的不同区域,或者甚至在可用RAM的情况下映射到HDD空间。耗尽。

您的输出包含超过8个十六进制数字的事实意味着您可能正在编译64位程序(使用最多16个十六进制数字的地址)。如果您重新编译32位程序,您会看到不同的输出。

答案 2 :(得分:2)

  1. 地址是指针的位置&#34; p&#34;在&#34;虚拟&#34;记忆过程。阅读&#34;虚拟内存管理&#34;了解操作系统如何管理内存。维基百科有一篇非常好的文章:Virtual Memory

  2. 局部变量的地址取决于两件事:1。编译器,以及2.操作系统加载进程的文本段的地方。大多数编译器将执行一些可能导致变量移动的优化技术。如果操作系统实现完整的ASLR,绝对位置也将改变。