C++ 指针能否指向4GB之后的地址?
如果我们编译并执行以下代码:C++ 指针能否指向4GB之后的地址?,c++,c,pointers,memory,C++,C,Pointers,Memory,如果我们编译并执行以下代码: int *p; printf("%d\n", (int)sizeof(p)); 似乎指向任何类型的指针的大小都是4字节,这意味着32位,因此232个地址可以存储在指针中。因为每个地址都与1个字节相关联,所以232个字节表示4GB 那么,在4GB内存之后,指针如何指向地址呢?一个程序怎么能使用超过4GB的内存呢?原则上,如果你不能表示一个超过2^X-1的地址,那么你不能处理超过2^X字节的内存 对于x86来说,这是正确的,即使已经实现并使用了一些变通方法(例如),允
int *p;
printf("%d\n", (int)sizeof(p));
似乎指向任何类型的指针的大小都是4字节,这意味着32位,因此232个地址可以存储在指针中。因为每个地址都与1个字节相关联,所以232个字节表示4GB
那么,在4GB内存之后,指针如何指向地址呢?一个程序怎么能使用超过4GB的内存呢?原则上,如果你不能表示一个超过
2^X-1
的地址,那么你不能处理超过2^X
字节的内存
对于x86来说,这是正确的,即使已经实现并使用了一些变通方法(例如),允许拥有更多的物理内存,即使这些方法比问题的实际解决方案更容易受到黑客的限制
在64位体系结构中,指针的标准大小是原来的两倍,因此您不必再担心了
记住,无论如何,虚拟内存将地址从进程空间转换为物理空间,因此很容易看出硬件可以支持更多内存,即使从进程的角度来看,最大可寻址内存仍然受到指针大小的限制。要访问>4GB的地址空间,可以执行以下操作之一:
- 在64位操作系统上以x86_64(64位)编译。这是最简单的
- 使用。AWE允许映射(通常)驻留在4GB以上的内存窗口。窗口地址可以一次又一次地映射和重新映射。在32位时代用于大型数据库应用程序和RAM驱动器
这样,如果有两个进程都使用4GB,那么在32位系统上可以使用8GB内存。Windows x64内核和为Windows x64编译的本机程序使用64位/8字节指针,因此可以使用更多内存。没错,32位程序不能。您必须编译为64位,其中指针为64位。在过去,指针为16位长时,内存寻址是通过分割内存并指向特定段中的某个位置来完成的。现在,当我们想要更大的范围时,我们只编译64位:P@PavelAnossov他问指针如何指向4GB以上的内存。它可以,甚至在32位处理器中,因为分页等原因。@user3125280当我说4GB之后的地址时,我指的是虚拟内存而不是物理内存。PAE使操作系统能够在32位上使用超过~4GB的内存,但是,没有哪个进程可以使用超过4GB的内存。在x86 64位上,指针大小为48位。@erenon“。这允许有更多的物理内存..”。我说的是物理记忆。PAE在这方面值得一提,不幸的是它并没有真正回答这个问题。有趣的是,它被标记为答案。当然,这完全取决于架构,因此对此持保留态度。从理论上讲,32位系统可以拥有所需的任意大的虚拟内存空间。只需使用32位指针的层次结构。“表示地址”还有其他方法。@rull如果它们是保留的,则必须为零。这就像看到一台收银机有四位数的价格空间,并询问额外的数字是什么,即使商店里没有任何东西的价格超过999欧元。这意味着,如果商店增加了1000欧元的东西,它就不必重新设计收银机。AWE是正确的,尽管有点挑剔。运行进程的用户帐户需要在内存中锁定页面的权限,这在默认情况下是禁用的,原因很充分。这使得有时很难将AWE程序放到生产机器上。这不是一个非常明确的答案-由于虚拟内存和分页,指针可以指向内存中的任何位置。AWE内存只是重新映射地址空间。@user3125280问题是:如何使用大于4GB的内存?怀着敬畏之心,你完全可以做到这一点。您不能一次访问所有数据,但这不是问题的一部分。@JensG正如您在答案下看到的,我认为问题是关于4GB之后的物理内存,而不是虚拟内存。所以,任何摆弄虚拟映射的东西,比如AWE,都是一个相关的答案。抱歉,您不需要AWE来分配和映射内存。只要一次映射不超过4GB,MapViewOfFile就可以正常工作。实际上,在典型的32位操作系统设计中,一个进程只能使用4GB的一小部分。我所说的分数是指1/2或3/4(在广泛使用的操作系统中发现的两个典型值)。