当超过可能的虚拟地址数时会发生什么

时间:2017-04-07 05:14:12

标签: c++ c

假设我正在为一个具有32位虚拟空间地址(4294967296地址)的环境编写程序,如果创建超过4294967296个变量,有效地超过可能的地址数,会发生什么?或者环境中的所有程序共同使用超过4294967296个地址?

5 个答案:

答案 0 :(得分:4)

这完全取决于你是如何尝试的。它可能会崩溃,它可能会返回一个错误,它可能会抛出异常。

答案 1 :(得分:3)

  

如果创建超过4294967296个变量

会发生什么

我猜你很困惑。你不会创造那么多变量。您实际上使用C dynamic memory allocation(使用malloc & free and friends)或C ++动态内存分配(例如dynamic memory managementlow level memory management以上::operator newmalloc,在许多实现中使用{ {1}})。

请注意,malloc(在C中)和new(在C ++中)不会创建新变量。他们正在分配新的内存区域,如果您在C中编写int *ptr = malloc(100000*sizeof(int);,或在C ++中编写int* ptr = new int[100000];地址可以进入一个指针变量....

variable(在C或C ++中)是一个源代码,它具有名称(例如ptrx000002array在这里的答案)和scope。在执行期间,只有位置很重要(并且变量不存在)。阅读memory addresses(实际上是什么位置)。

因此,要拥有许多变量,您需要拥有一个巨大的源文件:

int x000001;
int x000002;

等等。您可能可以生成(使用其他程序)如此庞大的C或C ++源文件,例如:最多:

////etc
int x999998;
int x999999;

但即使您生成了40亿行源C文件,您也无需耐心编译它。如果你这样做,编译肯定会失败(至少在link时间,我将其视为整个程序编译的一部分。)

请注意,数组声明只定义了一个变量:

/// one single variable, but a huge one
int array[4294967296];

声明一个名为array的变量。再次,这将无法编译和link(如果变量是某个函数中的 local 一个,那么在运行时你至少会获得stack overflow)。典型的call stacks限制为一个或几兆字节(这取决于操作系统和计算机)。

查看virtual address space wikipage 中的图片,了解pointer aliasing的含义以及virtual memory是什么。

实际上,在32位计算机上,虚拟地址空间通常限于例如给定process的3G字节数(每个进程运行一些executable并具有自己的虚拟地址空间)。详细信息是特定于操作系统在Linux上,使用setrlimit(2) - 可能通过bash shell的ulimit内置 - 来降低该限制。

在Linux上,动态内存分配(mallocnew)基于system calls修改虚拟地址空间,尤其是mmap(2)。此类调用可能会失败(然后malloc将因返回NULL而失败,new将引发异常),而在32位系统上,它们将在3G字节之前失败。您可能想要禁用memory overcommitment

如果您碰巧使用Linux系统,请阅读proc(5)并尝试

cat /proc/self/maps
cat /proc/$$/maps

然后了解他们的输出是什么。您可能还应该阅读Advanced Linux Programming

我建议花几天时间阅读:Operating Systems : Three Easy Pieces(可免费下载)。

(在Windows或MacOSX或Android上,mallocnew都使用某些操作系统原语来增加虚拟地址空间。我让你找到哪些内容)< / SUP>

答案 2 :(得分:3)

如果您的特定进程试图超过进程虚拟地址空间的大小,它将只是内存不足。当你的进程耗尽内存时通常会发生什么 - 内存分配函数将返回空指针或类似的东西。而且,从理论上讲,耗尽地址空间是唯一的方式,以便耗尽内存&#34;在支持交换的虚拟内存操作系统中(现实生活比这复杂一点,但总的来说确实如此)。

至于系统上的所有进程......你的问题是错误的。操作系统即使是32位操作系统,也不会以任何方式限制为所有进程的单个32位地址空间。对于所有实际的手段和目的,操作系统可以为不同的进程保持几乎不受限制的同时独立的32位地址空间。

答案 3 :(得分:2)

如果使用静态存储持续时间创建那么多变量,或者在一个块中创建自动变量,则编译器或链接器可能无法创建可执行文件。

如果在许多函数中创建了许多自动变量并导致所有函数同时处于活动状态,则程序将因堆栈溢出而崩溃。

如果您尝试从动态存储分配那么多字节,分配将失败。

答案 4 :(得分:1)

达到限制时,提交内存的虚拟分配将失败。这意味着即使是标准的32位进程也可能会导致虚拟内存分配失败。 也许该链接可以帮助您:Pushing the Limits of Windows: Virtual Memory