質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

1958閲覧

プログラムが標準入力を待たず終了する

takey

総合スコア312

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/09/21 10:25

編集2020/09/21 11:26

環境

環境はWindowsで、VSCodeのコンソールからコンパイルしています。

> g++ -v Using built-in specs. COLLECT_GCC=C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin\g++.exe COLLECT_LTO_WRAPPER=C:/Program\ Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/lto-wrapper.exe Target: x86_64-w64-mingw32 Configured with: ../../../src/gcc-8.1.0/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64 --enable-shared --enable-static --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-mpc=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-isl=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-pkgversion='x86_64-posix-seh-rev0, Built by MinGW-W64 project' --with-bugurl=https://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS=' -I/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include' LDFLAGS='-pipe -fno-ident -L/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/lib -L/c/mingw810/prerequisites/x86_64-zlib-static/lib -L/c/mingw810/prerequisites/x86_64-w64-mingw32-static/lib ' Thread model: posix gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)

現象

以下のプログラムをコンパイルして実行しても、標準入力を待たずにプログラムが終了します。

cpp

1/* d2.cpp*/ 2#include <bits/stdc++.h> 3using namespace std; 4 5void solve(){ 6 int N, K; 7 cin >> N >> K; 8 int grid[1005][2005]; // この行をコメントアウトすると、標準入力を待つようになる 9} 10 11 12int main(int argc, char const *argv[]){ 13 solve(); 14 return 0; 15}
> g++ d2.cpp > ./a > (標準入力を待たずプログラムが終了する)

原因がわかる方いらっしゃいますでしょうか?

よろしくお願いします。

追記[2020/09/21 19:36]

以下のように、static int grid[1005][2005];vector<vector<int>> grid(1005, vector<int>(2005, 0));に変更したら標準入力を待つようになりました。

cpp

1/* d2.cpp*/ 2#include <bits/stdc++.h> 3using namespace std; 4 5void solve(){ 6 int N, K; 7 cin >> N >> K; 8 // int grid[1005][2005]; // この行をコメントアウトすると、標準入力を待つようになる 9 static int grid[1005][2005]; // OK 10 // vector<vector<int>> grid(1005, vector<int>(2005, 0)); // OK 11} 12 13 14int main(int argc, char const *argv[]){ 15 solve(); 16 return 0; 17}

追記2[2020/09/21/ 19:51]

標準入力が最適化によって消えているのではないかという指摘がありましたので、以下のようにNKを出力するプログラムにしてみましたが、やはりプログラムは終了しました。

cpp

1// #include <bits/stdc++.h> 2#include <iostream> 3#include <vector> 4using namespace std; 5 6int solve(){ 7 int N, K; 8 cin >> N >> K; 9 int grid[1005][2005]; // この行をコメントアウトすると、標準入力を待つようになる 10 // static int grid[1005][2005]; // OK 11 // vector<vector<int>> grid(1005, vector<int>(2005, 0)); // OK 12 cout << N+K << endl; 13 return N+K; 14} 15 16 17int main(int argc, char const *argv[]){ 18 int ret; 19 ret = solve(); 20 cout << ret << endl; 21 return 0; 22}
> g++ abc/086/d2.cpp > ./a > (標準入力を待たずに終了する)

追記3(BA後)

多くの方がご指摘いただいているとおり、原因はスタックオーバーフローによるものだと思われます。

vectorだとOKな理由は、vectorはヒープ領域だからなようです。

https://cpprefjp.github.io/reference/vector/vector.html

配列と違い、ストレージはvector自体が管理するため、自動的に領域の拡張が行われる。

皆様ご回答いただきありがとうございました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cateye

2020/09/21 10:28

int grid[1005][2005];は、スタックには大きすぎませんか? 8M近く有りますよ。
hidezzz

2020/09/21 10:32

私も確保されているスタックサイズを越えている気がします。 根本的解決ではなく試すだけにしてほしいのですが、staticを付けて static int grid[1005][2005]; とするとどうなりますか?
takey

2020/09/21 10:37

追記いたしました。staticやvectorにしたら標準入力を待つようになりました。
Zuishin

2020/09/21 11:06

単に強制終了してるんでしょうね。
guest

回答3

0

ベストアンサー

関数の内部で「int grid[1005][2005];」のように変数宣言するとauto変数となりスタック領域に確保されますが、そのスタックサイズを越えてしまって誤動作を起こしているのだと思います。

gridという変数領域がどういうライフタイムを持つのか(持たせたいか)によって対処方法は変わると思います。

今の提示ソースのようにsolve()関数が呼ばれるたびに変数領域が確保されsolve()が終了した際に消滅して構わないのであれば、その位置で宣言すること自体は正しいのですが、スタックを極力消費しない方法で確保する必要があります。(vectorを使うのもひとつの方法です。)

gridの領域確保が全体で1回だけ必要でプログラムの開始から終了まで存在し続けるという使い方ならば、関数の外側で宣言すれば良いです(その際ただのグローバル変数ではなく、classに隠蔽したりしたほうが良いかもしれませんが)。これならばスタックサイズと関係なく確保されます。

もう一つ、スタックがどのぐらい大きくなるかがちゃんと見積もりを立てられるなら、リンカオプションでスタックサイズを増やすという手も一応あります。

投稿2020/09/21 11:06

編集2020/09/21 11:22
hidezzz

総合スコア1248

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takey

2020/09/21 11:10

vectorだとOKな理由がわからないんですが、配列とvectorではスタックに積まれるサイズが異なるのですか?(vectorもstaticにしない限りスタック領域に確保されますよね?)
hidezzz

2020/09/21 11:15 編集

自分も細かいところをツッコまれるとあやしいですが、vectorの管理領域はスタックに確保されますが、vectorの実データ領域は動的に(ヒープ領域?に)確保されるのだと思います。自動変数宣言した配列はスタックにまるごと確保されます。
takey

2020/09/21 11:23

ググったらvectorは「配列と違い自動的に領域の拡張が行われる」ようです。ヒープ領域っぽいですね。ありがとうございました。
guest

0

ソースコード上は関数の途中や最後に書いてあっても、ローカル変数の確保は多分関数に入ったところで行うでしょう。そのほうがスタックのやりくりが楽ですから。

ローカル変数のとりすぎでスタックオーバーフローで破綻したのでしょう。

投稿2020/09/21 11:06

thkana

総合スコア7703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

NやKが使用されてないために、最適化で削除されてそうな気がします

C++

1int solve(){ 2 int N, K; 3 cin >> N >> K; 4 return N+K; 5}

とでもやってみればどうなるでしょうか

投稿2020/09/21 10:48

y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takey

2020/09/21 10:54

追記しました。やはりプログラムは標準入力を待たず終了しました。
y_waiwai

2020/09/21 10:57

あとはアセンブルファイルを出力してみてどうなってるか見ることでしょうね
y_waiwai

2020/09/21 11:14

ああなんだ、逆に読み間違えてましたね。 結局AUTO変数でスタックオーバーして暴走してるだけですね
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問