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

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

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

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

Q&A

解決済

4回答

1025閲覧

C++でruntime errorがでます。runtime error: reference binding to null pointer of type 'int'

alizona

総合スコア126

C++

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

0グッド

0クリップ

投稿2020/06/21 19:53

編集2020/06/22 00:59

ランタイムエラーを引き起こしている原因がわからないです。
どの点を修正することで、ランタイムエラーを解決できるのかを教えていただきたいです

###発生しているエラー

C++

1Line 924: Char 9: runtime error: reference binding to null pointer of type 'int' (stl_vector.h) 2SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_vector.h:933:9

違う値をコードのテストに使用した場合にエラーが起きています

コーディングインタビュー練習サイトの問題のリンク

###要件定義

  • 2つのソートされた整数配列nums1とnums2が与えられた場合、nums2を1つのソートされた配列としてnums1にマージします。

  • nums1およびnums2で初期化される要素の数は、それぞれmおよびnです。

  • nums1には、nums2からの追加の要素を保持するのに十分なスペース(m + n以上のサイズ)があると想定できます。

###関数呼び出し時に使われる値
nums1 = [1,2,3,0,0,0]
nums2 = [2,5,6]

n=3
m=3

###期待される答え
nums1 = [1,2,2,3,5,6]

###エラーを起こすコード

C++

1class Solution { 2public: 3 void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) { 4 5 int n1=0; 6 int n2=0; 7 8 vector<int>tmp; 9 10 while(n1<nums1.size()){ 11 12 if(tmp.size()==0){ 13 14 if(n1>=m){ 15 //nums1が、初期値を指定された値を超えたとき [1,2,3,0,0,0] の3を超えて0になった時、nums2をただnums1に入れていく 16 nums1[n1]=nums2[n2]; 17 18 //n1とn2を次に進める 19 n1++; 20 n2++; 21 22 }else if(nums1[n1]>nums2[n2]){ 23 //1の方が大きいから2をリストnums1に挿入 24 //nums1 = [1,2,3,0,0,0] 25 //nums2 = [2,5,6] 26 //nums1の3とnums2の2を比べて、まずは、nums1[2]をtmpにkeepして、nums2[0]をnums1[2]に代入 27 28 if(n1<m){ 29 //tmpに保存 30 tmp.push_back(nums1[n1]); 31 } 32 33 //小さいnums2の値をnums1に上書き 34 nums1[n1]=nums2[n2]; 35 36 //n1とn2を次に進める 37 n1++; 38 n2++; 39 40 }else if(nums1[n1]<=nums2[n2]){ 41 //nums1 = [1,2,3,0,0,0] 42 //nums2 = [2,5,6] 43 //nums1の3とnums2の5では、nums1の方が小さいので、 44 //list nums1は変更せず、n1++をする 45 n1++; 46 } 47 }else{ 48 //tmp.size()!=0 49 //つまり、vectorに保管してる 50 51 if(n2==n-1){ 52 //もしnums2にもう要素が残っていないのなら、tmpに入っている値をnums1に挿入 53 nums1[n1]=tmp[0]; 54 55 //tmpのheadを削除する。 56 tmp.erase(tmp.begin()); 57 n1++; 58 59 //tmpは、上書きされる前に退避させたn1の値だから tmpとn2を比較する 60 }else if(tmp[0]>nums2[n2]){ 61 //n2の方が小さいということは、nums2をnums1に上書きする 62 //そのため、nums1の値が消えてしまうので、tmpに退避させとく 63 tmp.push_back(nums1[n1]); 64 //上書き 65 nums1[n1]=nums2[n2]; 66 n1++; 67 n2++; 68 69 }else if(tmp[0]<=nums2[n2]){ 70 //tmpの方がnums2より小さいときは、 71 //vectorの先頭の値をnums1に上書きする 72 73 //n1がmより小さいときは、上書きされるn1をtmpに退避させる 74 //nums1 = [1,2,3,0,0,0] mとは、nums1[2]まで、 75 //nums2 = [2,5,6] 76 77 if(n1<m){ 78 tmp.push_back(nums1[n1]); 79 }else{ 80 //0を上書きする場合は、0をtmpに退避させる必要はない 81 } 82 nums1[n1]=tmp[0]; //nums1から一度tmpに退避したが、h再び、nums1の順序順のindexに戻した 83 //tmpのheadを削除する。 84 tmp.erase(tmp.begin()); 85 n1++; 86 } 87 } 88 } 89 } 90}; 91 92

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

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

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

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

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

guest

回答4

0

nums1 = [1,2,3,0,0,0]
nums2 = [2,5,6]
n=3
m=4

m=3 のマチガイちゃいます?

[追記] m = 1, n = 0 でやってみると:

C++

1 else if (nums1[n1] > nums2[n2]) { // ******* ココ! 2 //1の方が大きいから2をリストnums1に挿入

ココでコケます。num2は空、すなわちnums2[n2]は存在しませんから。

投稿2020/06/22 00:43

編集2020/06/22 01:11
episteme

総合スコア16612

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

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

alizona

2020/06/22 00:52

そうでした。ただこの問題は、teratail上のみでの書き間違えでした。
alizona

2020/06/22 00:57

Runtime Errorの詳細である、Submittion reportのスクリーンショットを追加させていただきました。
episteme

2020/06/22 01:11

やってみた。たしかにコケます。追記しました。
guest

0

[回答ではありません]

C++

1#include <iostream> 2#include <vector> 3 4int main() { 5 6 std::vector<int> nums1 = { 1, 2, 3 }; 7 std::vector<int> nums2 = { 2, 5, 6 }; 8 9 std::vector<int> result; // num1とnum2をマージした結果 10 11 std::vector<int>::iterator iter1 = nums1.begin(); 12 std::vector<int>::iterator iter2 = nums2.begin(); 13 // 両方要素がある間は 14 while ( iter1 != nums1.end() && iter2 != nums2.end() ) { 15 // 小さい方を積む 16 if ( *iter1 < *iter2 ) { 17 result.push_back(*iter1++); 18 } else { 19 result.push_back(*iter2++); 20 } 21 } 22 // 積み残しを全部積む 23 while ( iter1 != nums1.end() ) { result.push_back(*iter1++); } 24 while ( iter2 != nums2.end() ) { result.push_back(*iter2++); } 25 26 // できたかな? 27 for ( int item : result ) { std::cout << item << ' '; } 28 std::cout << std::endl; 29}

[追記] 題意に沿ってみた。std::rotateだけは使わせてね♪

C++

1#include <iostream> 2#include <vector> 3#include <algorithm> 4 5class Solution { 6public: 7 void merge(std::vector<int>& nums1, int m, std::vector<int>& nums2, int n) { 8 std::vector<int>::iterator first1 = nums1.begin(); 9 std::vector<int>::iterator last1 = first1 + m; 10 std::vector<int>::iterator first2 = nums2.begin(); 11 std::vector<int>::iterator last2 = first2 + n; 12 // 両方要素があるうちは小さい方を積む 13 while ( first1 != last1 && first2 != last2 ) { 14 if ( *first1 < *first2 ) { 15 // 1側を積むのは"次へ進む"だけ 16 ++first1; 17 } else { 18 // 2側を積むのはちょっと面倒、1側の末尾に積んでくるっと回転 19 *last1 = *first2++; 20 std::rotate(++first1, last1, last1+1); 21 ++last1; 22 } 23 } 24 // 残った2側を全部積む 25 while( first2 != last2 ) { *last1++ = *first2++; } 26 } 27}; 28 29int main() { 30 31 std::vector<int> nums1 = { 1, 2, 3, 0, 0, 0 }; 32 std::vector<int> nums2 = { 2, 5, 6 }; 33 Solution s; 34 s.merge(nums1, 3, nums2, 3); 35 for (int item : nums1 ) { std::cout << item << ' '; } 36 std::cout << std::endl; 37}

投稿2020/06/21 22:32

編集2020/06/21 23:23
episteme

総合スコア16612

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

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

alizona

2020/06/21 22:54

ありがとうございます。 私の実現しようとしているコードの動作と同じ動作をしました。 コードの量が少なく、私のコードがいかに助長かを感じます。 勉強になります。
episteme

2020/06/21 23:24

題意に沿った版を追記しました。
alizona

2020/06/21 23:32

説明不足で、また回答いただいて、すみません。 ありがとうございます。
guest

0

tmp は初期化されてませんね

投稿2020/06/21 21:31

y_waiwai

総合スコア88042

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

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

alizona

2020/06/21 21:51

回答していただき、ありがとうございます。 tmpを定義したあと、vector<int>tmp{};や、vector<int>tmp(); などをやりましたが、結果は同じでした。 初期化する方法が間違っていますでしょうか?
y_waiwai

2020/06/21 21:52

間違ってます tmpになにを入れたいのでしょうか
alizona

2020/06/21 22:00

tmpの使い道としては、 list1 [1,2,4,0,0,0] list2 [3,5,6] この2つのリストを連結して並び替える時に、 3をlist1[2] に代入する前に、 list1[2]の値を保存しておくために、 tmp.push_back(list1[2])とします。 そのため、定義した時点では、tmpをからにしておきたいです。 その後、tmpにpush_back()されたあとは、tmpの値と、list2の値を比較して並び替えの続きをします。
guest

0

自己解決

while(n1<nums1.size()){

while(n1<nums1.size()-1){

に変更することによって、runtime errorが改善されました。

アドバイスや、回答のサンプルをいただいたみなさまありがとうございました。
今後ともよろしくお願いいたします。


LeetCodeという練習サイトで自動テストをしてくれるのですが、やっとクリアしました。コードをここにあげます。

C++

1 class Solution { 2public: 3 void merge(vector<int>& numFirst, int fLength, vector<int>& numSecond, int sLength) { 4 5 int F=0; 6 int S=0; 7 8 vector<int>tmp; 9 10 while(sLength !=0 && F<numFirst.size()){ 11 12 if(tmp.size()==0){ 13 if(S==sLength){ 14 F++; 15 16 }else if(F>=fLength || fLength==0){ 17 18 numFirst[F]=numSecond[S]; 19 F++; 20 S++; 21 22 }else if(numFirst[F]>numSecond[S]){ 23 if(F<fLength){ 24 tmp.push_back(numFirst[F]); 25 } 26 numFirst[F]=numSecond[S]; 27 F++; 28 S++; 29 30 }else if(numFirst[F]<=numSecond[S]){ 31 F++; 32 } 33 34 ///////////////////////////////tmpあり//////////////////// 35 }else{ 36 if(S==sLength){ 37 if(F<fLength){ 38 tmp.push_back(numFirst[F]); 39 numFirst[F]=tmp[0]; 40 tmp.erase(tmp.begin()); 41 }else{ 42 numFirst[F]=tmp[0]; 43 tmp.erase(tmp.begin()); 44 } 45 F++; 46 47 }else if(tmp[0]>numSecond[S]){ 48 if(F<fLength) 49 tmp.push_back(numFirst[F]); 50 numFirst[F]=numSecond[S]; 51 F++; 52 S++; 53 54 }else if(tmp[0]<=numSecond[S]){ 55 if(F<fLength){ 56 tmp.push_back(numFirst[F]); 57 } 58 numFirst[F]=tmp[0]; 59 tmp.erase(tmp.begin()); 60 F++; 61 } 62 } 63 } 64 } 65}; 66

投稿2020/06/22 01:03

編集2020/06/22 05:11
alizona

総合スコア126

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

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

episteme

2020/06/22 01:16

それだと std::vector<int> nums1 = { 0 }; std::vector<int> nums2 = { 1 }; Solution s; s.merge(nums1, 0, nums2, 1); のとき結果おかしくね?
alizona

2020/06/22 02:07

[0] 0 [1] 1 の時にエラーが起きないようにしました。 修正に取り組んでいたのですが、遅くなりもうしわけありません。 while(n !=0 && n1<nums1.size()){ if(tmp.size()==0){ if(n1>=m || m==0){ nums1[n1]=nums2[n2];
alizona

2020/06/22 02:08

違うエラーは出るのですが、また次のケースに対応できるように改善します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問