前提
該当のソースコードにあるようなC++プログラムを実行すると、パソコン自体がクラッシュしてしまいます。理由自体はある程度わかっていて、宣言した配列のサイズが大きすぎるからだろうと思われます。
ただプログラムがエラーを出して終了するなら良いとしても、パソコン自体がクラッシュしたのは今までにないことなのでその原因を知りたいです。よろしくお願いします。
確認したいこと
お聞きしたい点は以下の4つです。
- 原因はなんだろうか?
- あるプログラムを実行しただけでパソコンがクラッシュして、再起動してしまうのは正常と言えるか?
- もし正常なら、C++プログラムは常にそういったことに留意して書かれているのだろうか?(配列外参照などの話ではなくて、プログラム次第でコンピュターがクラッシュするかもしれないという点)
- これは私の環境特有の問題なのか?
私のOSの理解だとプログラムが実行される時に必要なリソースを渡し、それ以外の領域にはプログラムはアクセスできないようにしているはずで、プログラムの実行が失敗してもパソコン自体のクラッシュは起こりえないのではと考えていました。
補足
該当のプログラムを実際に動かそうしているわけではありません。ただ最初誤って該当のプログラム(主要箇所を抽出したものなので実際はもう少し書いてあった)を実行したところ、いきなりクラッシュから再起動し始めて疑問が湧いたということです。というわけで、知りたいことは「該当のプログラムを動かす方法」ではなく、「クラッシュした理由」ということになります。
発生している問題・エラーメッセージ
該当のソースコードをコンパイルし実行すると、5秒程度画面が固まり、操作が効かなくなります。その後画面が暗転し数秒経って再起動が始まります。
該当のソースコード
C++
1#include <bits/stdc++.h> 2using namespace std; 3 4using ll = long long; 5 6constexpr ll sz = 101010; // sz ~ 10^5 7ll table[sz][sz]; 8 9int main() { 10 ll n,W; 11 cin >> n >> W; 12 cout << n << "\n"; 13 14 15 return 0; 16}
試したこと
- 該当のソースコードを10回程度実行して試してみて、全てにおいて上記の現象が起こったので偶然が重なって起きたクラッシュではないと思われます。
- またVSCodeとFinder以外のアプリを立ち上げずに実行しても同様の現象が確認されました。
- コードでszを100にした場合はちゃんと動作し、クラッシュもしませんでした。
補足情報
実行環境
C++17.
コンパイラ:Apple clang version 13.1.6 (clang-1316.0.21.2.3)
MacBook Pro (M1, 2020) メモリ16GB, SSD 500GB
macOS: Monterey バージョン12.3.1
本来clangにはない<bits/stdc++.h>をincludeしてますが、これは拾ってきたbits/stdc++.hをincludeフォルダに入れている形で解決しています。
追記
- VSCodeで実行していると書きましたが、VSCodeの統合ターミナルよりコマンドで実行しております。
- 普段はコンパイルオプションを-std=c++17としてコンパイルしてますが、c++11としても同様のエラーが確認できました。
- jbpb0様のIntel Macメモリ16GBでは正常に動作する。(修正依頼参照) おそらくコンパイラは問題ではなくM1チップに関する問題?。
- 再起動時の問題レポート冒頭は次のとおりです。
panic(cpu 4 caller 0xfffffe001768b03c): Failed to reserve GPU Carveout region in user map 0xfffffe24cbfaa808 3 @vm_map.c:13285 Debugger message: panic Memory ID: 0xff OS release type: User OS version: 21E258 Kernel version: Darwin Kernel Version 21.4.0: Fri Mar 18 00:47:26 PDT 2022; root:xnu-8020.101.4~15/RELEASE_ARM64_T8101
- また配列サイズszを101,010から71,010に変更すると再起動は起こらず、./a.out実行時に次のエラーログが出る。コンパイルはエラーなく正常にできます。1行目でdyld_shared_cache_arm64eとあって、arm64つまりM1に関わるところだろうと思います。
dyld[1704]: dyld cache '/System/Library/dyld/dyld_shared_cache_arm64e' not loaded: syscall to map cache into shared region failed dyld[1704]: Library not loaded: /usr/lib/libc++.1.dylib Referenced from: /Users/<NAME>/Desktop/programming/kyopuro/pra/a.out Reason: tried: '/usr/lib/libc++.1.dylib' (no such file), '/usr/local/lib/libc++.1.dylib' (no such file) zsh: abort ./a.out
- ヒープに確保するよう変えると動作した。
actorbug様より
ヒープに確保するようにしたら、挙動が変わりませんかね。
C++
1ll table[sz][sz]; 2 ↓ 3ll (*table)[sz] = (ll(*)[sz])malloc(sizeof(ll) * sz * sz);
このようにすると再起動することなく、正常終了することを確認。
jbpb0様のコードのように
C++
1for(int i=0; i<sz; i++ ){ 2 for(int j=0; j<sz; j++ ){ 3 table[i][j]=i+j; 4 } 5}
を加えて実行した。アクティビティモニタでの最大メモリ使用量は実行時に大幅に増えたものの使用済みメモリ14GB程度であった。
プロセスのswap含めた最大メモリ使用量を確認したところ、74GBとなりました。
以下のコードのようにcinの前に二重ループを起き、入力せず変化がなくなるまで待ったところ76.06GBとなりました。
C++
1int main() { 2 ll n, W; 3 for(int i = 0; i < sz; i++) { 4 for(int j = 0; j < sz; j++) { 5 table[i][j] = i + j; 6 } 7 } 8 cin >> n >> W; 9 cout << n << "\n"; 10 return 0; 11}
まとめると
jbpb0様のIntel Macでll table[sz][sz];
として実行した結果と
私のM1 Macでll (*table)[sz] = (ll(*)[sz])malloc(sizeof(ll) * sz * sz);
として実行した結果及びメモリ使用量がほぼ同じとなる

回答3件
あなたの回答
tips
プレビュー