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

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

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

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

Q&A

解決済

1回答

971閲覧

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

ROSSY0127

総合スコア14

C++

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

0グッド

0クリップ

投稿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

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

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

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

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

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

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]と書いていたのがエラーの原因ですね。 かなり初歩的なミスでした。 ありがとうございます!
guest

回答1

0

自己解決

すみません、解決したので締め切らせてください!
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

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問