素朴な質問かもしれませんが...
確認または拒否:
自動および静的ストレージ期間のオブジェクト/変数のメモリの存在はコンパイル時に決定され、自動オブジェクトに十分なメモリがなかったためにプログラムが実行時に失敗する可能性はまったくありません。
当然、自動オブジェクトのコンストラクターが動的割り当てを実行し、そのような割り当てが失敗した場合、これは動的割り当ての失敗であり、自動ではないと見なされます。
素朴な質問かもしれませんが...
確認または拒否:
自動および静的ストレージ期間のオブジェクト/変数のメモリの存在はコンパイル時に決定され、自動オブジェクトに十分なメモリがなかったためにプログラムが実行時に失敗する可能性はまったくありません。
当然、自動オブジェクトのコンストラクターが動的割り当てを実行し、そのような割り当てが失敗した場合、これは動的割り当ての失敗であり、自動ではないと見なされます。
自動割り当ては確実に失敗する可能性があります。これは通常、スタック オーバーフローとして知られています。これは、誰かがローカル変数として大きな配列を変更しようとしたときによく見られます。無制限 (または十分に制限されていない) 再帰もこれを引き起こす可能性があります。
プラットフォームに依存しない方法で実際にできないことは、自動割り当ての失敗を検出して処理することです。
2 つの単語:スタック オーバーフロー。:P
オーバーコミットのあるシステム(デフォルト構成のLinuxなど)では、静的ストレージ期間のオブジェクトが実行時に障害を引き起こす可能性さえあります。プログラムの起動時に、これらのオブジェクトは、コピーオンライトのゼロページ(初期化されていない場合)またはディスク上の実行可能ファイルのコピーオンライトマッピングのいずれかに存在します。それらに最初に書き込もうとすると、ページフォールトが発生し、カーネルはプロセスのローカルで変更可能なコピーを作成します。カーネルが不注意で、プロセスにコミットしたほど多くのメモリを予約しなかった場合、これは失敗する可能性があり、その結果、恐ろしいOOMキラーになります。
この問題を抱えている堅牢なシステムはありません。Linuxの動作は次の方法で修正できます。
echo "2" > /proc/sys/vm/overcommit_memory
違います。自動割り当てによりスタック オーバーフローが発生する可能性があり、これにより、私が認識しているほとんどのアーキテクチャ/プラットフォームでプロセスが即座に終了します。
また、プログラムが基礎となるプラットフォームから静的変数に十分なスペースを割り当てることができない可能性があります。その場合、プログラムは引き続き失敗しますが、main
呼び出される前に失敗します。
簡単な反例:
#include <string.h>
int main()
{
int huge[0x1FFFFFFF]; // Specific size doesn't matter;
// it just has to be bigger than the stack.
memset(huge, 0, sizeof(huge) / sizeof(int));
return 0;
}
例:
#include <iostream>
using namespace std;
class A
{
public:
A() { p = new int[0xFFFFFFFF]; }
private:
int* p;
};
static A g_a;
int main()
{
cout << "Why do I never get called?" << endl;
}