Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 指针能否指向4GB之后的地址?_C++_C_Pointers_Memory - Fatal编程技术网

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驱动器
请注意,MSB为1的内存地址是为内核保留的。Windows允许在几种情况下使用最多3GB(每个进程),最高1GB总是用于内核

默认情况下,32位进程具有2GB的用户模式地址空间。可以通过一个特殊的链接器标志(在VS:/LargeAddressWare中)获得3GB的内存。

“一个指针怎么能指向4GB内存之后的地址?”

处理器可用的物理内存与进程看到的“虚拟内存”之间存在差异。32位进程(指针大小为4字节)限制为4GB,但处理器维护一个映射(由操作系统控制),使每个进程都有自己的内存空间,每个进程最多4GB


这样,如果有两个进程都使用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(在广泛使用的操作系统中发现的两个典型值)。