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

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

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

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

Q&A

解決済

segmentation faultの原因がどうしてもわかりません!!

ROSSY0127
ROSSY0127

総合スコア14

C++

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

1回答

0グッド

0クリップ

309閲覧

投稿2022/11/20 18:08

前提

とあるプログラミングサイトの問題を解いているのですが、下記のプログラムを実行するとSegmentation faultになります。
Segmentation faultが発生する場所は特定できたのですが(ソースコード中に記載してます)、なぜここで発生するのかわかりません。
初めはエラーが出なかったのですが、プログラムを細かくいじっているうちに出るようになり、エラーが消えなくなりました。
C++に詳しい皆様お助けいただけると幸いです。

念のため説明すると、このプログラムは1からUBまでの整数について素数の和で表す方法が何通りあるか調べるプログラムです。

実現したいこと

  • 計算結果を得たい

発生している問題・エラーメッセージ

Segmentation fault (core dumped)

該当のソースコード

C++

1#include <iostream> 2#include <vector> 3#include <iomanip> 4 5const int UB = 20; 6 7int main() 8{ 9 bool* isPrime; 10 try { 11 isPrime = new bool[UB]; 12 } catch (std::bad_alloc) { 13 std::cerr << "BA" << std::endl; 14 return 1; 15 } 16 for (int p=2; p<UB; p++) isPrime[p] = true; 17 isPrime[0] = isPrime[1] = false; 18 std::vector<int> v; 19 v.push_back(0); 20 for (int p=2; p<UB; p++) { 21 if (!isPrime[p]) continue; 22 v.push_back(p); 23 for (int q=2*p; q<UB; q+=p) isPrime[q] = false; 24 } 25 int L = v.size(); 26 int** DP; // DP[i][j] = the number of different ways of making i with numbers at most Pj 27 try { 28 DP = new int*[UB]; 29 for (int i=0; i<UB; i++) { 30 DP[i] = new int[L]; 31 } 32 } catch (std::bad_alloc) { 33 std::cerr << "BA" << std::endl; 34 return 1; 35 } 36 for (int i=0; i<UB; i++) { 37 int j=1; 38 DP[i][0] = i==0 ? 1 : 0; 39 std::cout << "check1" << std::endl; 40 // ここまで通る 41 for (; j<L && v[j]<=i; j++) { 42 // ここから通らない 43 std::cout << "check2" << std::endl; 44 int sum = 0; 45 for (int k=0; k<=j; k++) { 46 if (i-v[k] > v[j]) continue; 47 int l; 48 if (i-v[k] < v[k]) { 49 for (l=k; v[l]>i-v[k]; l--); 50 } else { 51 l = j; 52 } 53 sum += DP[v[k]][l]; 54 } 55 DP[i][j] = sum; 56 } 57 for (; j<L; j++) DP[i][j] = DP[i-1][j]; 58 if (DP[i][L-1] >= 5000) { 59 std::cout << i << std::endl; 60 break; 61 } 62 } 63 std::cout << " "; 64 for (int j=0; j<L; j++) std::cout << std::setw(3) << v[j] << " "; 65 std::cout << std::endl; 66 for (int i=0; i<UB; i++) { 67 std::cout << std::setw(3) << i << " "; 68 for (int j=0; j<L; j++) std::cout << std::setw(3) << DP[i][j] << " "; 69 std::cout << std::endl; 70 } 71 for (int i=0; i<UB; i++) delete[] DP[i]; 72 delete[] DP; 73 delete[] isPrime; 74 return 0; 75}

試したこと

MSYSの他のソフト(MSYS2 Clang,minGWなど)でもコンパイル&実行してみましたが、どれも同じ結果でした。

補足情報(FW/ツールのバージョンなど)

エディタ:Visual Studio Code 1.73.0
実行環境:MSYS2 MSYS mintty 3.6.4

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

hoshi-takanori

2022/11/20 18:34

細かく変数の動きを見ていけばいいと思いますが、最初の check1 の時点で i = 0, j = 1, v[j] = 2 なので、次の for 文の条件 v[j]<=i を満たさず、check2 を含むループは素通りして、for (; j<L; j++) DP[i][j] = DP[i-1][j]; のところで i = 0 なので i - 1 = -1 となり、落ちてるようですね。
ROSSY0127

2022/11/20 18:42

なるほど! 本来DP[i][j] = DP[i][j-1] とすべきところを、DP[i][j]=DP[i-1][j]と書いていたのがエラーの原因ですね。 かなり初歩的なミスでした。 ありがとうございます!

回答1

2

自己解決

すみません、解決したので締め切らせてください!
DP[i][j] = DP[i-1][j];
となっている箇所を
DP[i][j] = DP[i][j-1];
と書き直すと動作しました。
i=0のときに添え字が負となり、segmentation faultの原因になっていたようです。
失礼しました。

投稿2022/11/20 18:44

ROSSY0127

総合スコア14

pig_vba, ps_aux_grep👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

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

ただいまの回答率
86.02%

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

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

質問する

関連した質問

同じタグがついた質問を見る

C++

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