C++ 程序在新抛出错误之前被中止

C++ 程序在新抛出错误之前被中止,c++,operating-system,C++,Operating System,下面是一个小型C++程序,在“new”引发异常之前,它在许多情况下都会被中止: int main(){ try{ while(true) new char[2]; } catch(...){ while(true); } } 该程序首先用MinGW/g++4.6.1编译,然后通过shell在32位windows7系统上执行。当时没有其他严重的程序(在内存/CPU消耗方面)在运行。程序在进入catch块之前终止。在Linux(De

下面是一个小型C++程序,在“new”引发异常之前,它在许多情况下都会被中止:

int main(){
   try{
      while(true)
         new char[2];
   }
   catch(...){
      while(true);
   }
}
该程序首先用MinGW/g++4.6.1编译,然后通过shell在32位windows7系统上执行。当时没有其他严重的程序(在内存/CPU消耗方面)在运行。程序在进入catch块之前终止。在Linux(Debian 7.3,gcc/c++4.7.2,24GB内存)下编译和运行程序时,程序的行为类似。(catch块中使用无限循环的原因是为了避免任何可能引发异常的情况,特别是I/O。) 在Windows系统上两次启动程序时(至少对我来说)发生了一些令人惊讶的事情:如果程序在两个不同的shell中(几乎)同时启动,那么两个进程都不会在抛出新异常之前终止。 我也没有想到的是,只有适度扩大分配内存块的大小(将第四行中的“2”替换为“9”)才能在Windows系统上消除过早终止。在Linux机器上,需要进行更大的扩展以避免终止:每个块大约需要40000000字节来防止终止

我错过了什么?这是相关操作系统的正常/预期行为吗?如果是这样的话,这难道不会削弱异常的有用性——至少在动态分配失败的情况下是这样吗?是否可以(由用户)以某种方式修改操作系统设置以防止此类过早终止?最后,关于“严重的”应用程序:在什么情况下(从w.r.到动态内存分配),我必须担心我的应用程序被操作系统突然中止

这是相关操作系统的正常/预期行为吗

是的,它被称为“过度分配”或“惰性分配”。Linux(我认为是Windows,但我从未为该操作系统编程)会在您请求时为进程分配虚拟内存,但在您访问它之前不会尝试分配物理内存。在这一点上,如果没有可用的RAM或交换空间,程序将失败。或者,至少在Linux的情况下,其他进程可能会被随机杀死,以便您可以掠夺它们的内存

注意,在这样做小的分配时,进程将分配更大的块并将它们放在堆中;因此,通常会立即访问分配的内存。一个大的分配将直接从操作系统分配,因此您的测试程序将不会访问该内存-这就是为什么您观察到,当您分配大的块时,程序没有中止

如果是这样的话,这难道不会削弱异常的有用性——至少在动态分配失败的情况下是这样吗

是的,的确如此

是否可以(由用户)以某种方式修改操作系统设置以防止此类过早终止

在Linux上,有一个系统变量来控制Overmit策略:

echo 2 > /proc/sys/vm/overcommit_memory
值2表示永不过度分配-如果分配请求的内存超过当前未提交的RAM加交换,则分配将失败。1表示分配永不失败。0(默认值)表示猜测分配请求是否合理

我不知道Windows是否具有类似的可配置性

这是相关操作系统的正常/预期行为吗

是的,它被称为“过度分配”或“惰性分配”。Linux(我认为是Windows,但我从未为该操作系统编程)会在您请求时为进程分配虚拟内存,但在您访问它之前不会尝试分配物理内存。在这一点上,如果没有可用的RAM或交换空间,程序将失败。或者,至少在Linux的情况下,其他进程可能会被随机杀死,以便您可以掠夺它们的内存

注意,在这样做小的分配时,进程将分配更大的块并将它们放在堆中;因此,通常会立即访问分配的内存。一个大的分配将直接从操作系统分配,因此您的测试程序将不会访问该内存-这就是为什么您观察到,当您分配大的块时,程序没有中止

如果是这样的话,这难道不会削弱异常的有用性——至少在动态分配失败的情况下是这样吗

是的,的确如此

是否可以(由用户)以某种方式修改操作系统设置以防止此类过早终止

在Linux上,有一个系统变量来控制Overmit策略:

echo 2 > /proc/sys/vm/overcommit_memory
值2表示永不过度分配-如果分配请求的内存超过当前未提交的RAM加交换,则分配将失败。1表示分配永不失败。0(默认值)表示猜测分配请求是否合理

我不知道Windows是否具有类似的可配置性

这是相关操作系统的正常/预期行为吗

是的,它被称为“过度分配”或“惰性分配”。Linux(我认为是Windows,但我从未为该操作系统编程)会在您请求时为进程分配虚拟内存,但在您访问它之前不会尝试分配物理内存。在这一点上,如果没有可用的RAM或交换空间,程序将失败。或者,至少在Linux的情况下,其他进程可能会被随机杀死,以便您可以掠夺它们的内存

注意,在这样做小的分配时,进程将分配更大的块并将它们放在堆中;因此,通常会立即访问分配的内存。一个大的分配将直接从操作系统分配,因此您的测试程序将不会访问该内存-这就是为什么您观察到,当您分配大的块时,程序没有中止

如果是这样的话,这难道不会削弱异常的有用性——至少在动态分配失败的情况下是这样吗

是的,的确如此