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

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

新規登録して質問してみよう
ただいま回答率
85.48%
機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

C++

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

Q&A

解決済

1回答

1882閲覧

構造体のvectorをpush_backする過程で問題が生じている?

rosbergf1

総合スコア13

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

C++

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

0グッド

0クリップ

投稿2018/10/02 13:33

編集2018/10/02 17:45

前提・実現したいこと

要素数が6のベクトルを代入したいのですが, デバッグで見ていくと, 代入されていたり, 要素数が0になっていたりする.

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

ベクトルを代入する関数が2つあるのですが, 片方はうまく代入できているのですが, もう一方の関数できちんと代入されていなく, 要素数が0になっている.

//うまく行った場合 a = size=6 { [0] = 85 [1] = 52.500147820000002 [2] = 0.70422535200000003 [3] = 60 [4] = 78.157357930000003 [5] = 40.270996089999997 } //失敗している場合 a = size=0 {}

該当のソースコード

C++

1//構造体の中身 2typedef struct { 3 vector<double> a; 4 double p; 5 double e; 6 double k; 7 double F; 8 int exp; 9 double as; 10 int ts; 11 int MS; 12 int AS; 13} Classifier; 14//途中部分は省略... 15 16void CSAddset(vector<Classifier>& CS) { 17 int i; 18 CS.push_back(CS[0]); 19 i = CS.size() - 1; 20 //RNN 21 FirstCS_RNN(CS, i); 22 CS[i].p = 0.1; 23 CS[i].e = 0.1; 24 CS[i].F = 0.1; 25 CS[i].exp = 0; 26 CS[i].as = 0; 27 CS[i].ts = 0; 28 CS[i].MS = 0; 29 CS[i].AS = 0; 30} 31 32//この関数内のAddsetで問題が生じる. 33void covering(vector<Classifier>& CS, const vector<double>& data, vector< vector<double> >& valuepattern, const int t, const string Func) { 34 int i, j, k, n; 35 int nownumber; 36 vector <vector<double> > notvalue; 37 vector<double> action; 38 int counter = 0; 39 //マッチセットの中の行動をカウント 40 for(i = 0; i < valuepattern.size(); i++) { 41 for(j = 0; j < CS.size(); j++) { 42 if(CS[j].MS == 1) { 43 if(CS[j].a == valuepattern[i]) { 44 counter++; 45 break; 46 } 47 else { 48 notvalue.push_back(valuepattern[i]); 49 } 50 } 51 } 52 } 53 //10種類の行動があればカバーリングを行わずに終了 54 if(counter >= 10) 55 return; 56 57 //行動が10種類なければカバーリングを行う 58 nownumber = CS.size(); 59 if(counter > 0) { 60 for(i = 0; i < notvalue.size() - counter; i++) { 61 //rm_cs_of_MAX(CS, n); 62 CSAddset(CS); 63 for(j = 0; j < CS.size(); j++) { 64 if(CS[j].a.size() == 0) { 65 cout << i+1 << "回目" << "Addsetおかしいぞ" << endl; 66 abort(); 67 } 68 } 69 k = CS.size() - 1; 70 CS[k].a = notvalue[i]; 71 do { 72 CS_propagation(CS, data, t, k, Func); 73 CS_BPTT(CS, data, t, k, Func); 74 } while(CS[k].RNN.o.n[0] <= CS[k].RNN.o.n[1]); 75 CS[k].MS = 1; 76 k++; 77 } 78 } 79 else { 80 for(i = 0; i < valuepattern.size(); i++) { 81 //rm_cs_of_MAX(CS, n); 82 CSAddset(CS); 83 for(j = 0; j < CS.size(); j++) { 84 if(CS[j].a.size() == 0) { 85 cout << i+1 << "回目" << "Addsetおかしいぞ" << endl; 86 abort(); 87 } 88 } 89 k = CS.size() - 1; 90 CS[k].a = valuepattern[i]; 91 do { 92 CS_propagation(CS, data, t, k, Func); 93 CS_BPTT(CS, data, t, k, Func); 94 } while(CS[k].RNN.o.n[0] <= CS[k].RNN.o.n[1]); 95 CS[k].MS = 1; 96 k++; 97 } 98 } 99 rm_cs_of_add(CS); 100}

やってみたこと

vectorの構造体を追加したあとにいろいろとメンバ変数に代入しているのですが, その過程で問題が生じているみたいです.
追記*
デバッグで追ったところ, 関数covering内のAddsetを実行後に要素が0になっていることがわかりました.
合わせて, Addsetも追記しておきます.
コメント文では, "2回目Addsetおかしいぞ"と出力されるので, 2回目の実行からおかしくなっているものと思われます.
よろしくお願いします.

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

環境はMacです.

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

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

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

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

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

guest

回答1

0

ベストアンサー

CS[j].a が空の配列なのが意図どおりではないということですよね。
代入している valuepattern[i] が空の配列でないということは確認してあるのでしょうか?

CS[j].a = valuepattern[i];

std::vector の代入は各要素の値コピーが行われます。
代入元の配列が空でなければ、代入先の配列も空にはなりません。

cpp

1#include <iostream> 2#include <vector> 3 4int main() 5{ 6 std::vector<int> array1 = {1, 2, 3, 4, 5}; 7 for (const auto &v : array1) 8 std::cout << v << " "; 9 std::cout << std::endl; 10 11 std::vector<int> array2; 12 std::cout << "array2.size(): " << array2.size() << std::endl; 13 14 array2 = array1; // コピーコンストラクタ 15 for (const auto &v : array2) 16 std::cout << v << " "; 17 std::cout << std::endl; 18} 19

output

11 2 3 4 5 2array2.size(): 0 31 2 3 4 5

投稿2018/10/02 13:57

編集2018/10/02 14:22
tiitoi

総合スコア21956

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

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

rosbergf1

2018/10/02 14:06

デバッグでvaluepatternについては確認していて, 空の配列はひとつもなかったので, valuepatternに起因する問題ではないことは確認しています. なんか関数coveringの中の関数AddCSsetでp, e, fに(0, 1)の乱数を代入しているのですが, それに関しても0になってしまっているんですよね. vector自体が使い始めてまだ日が浅いので仕組みをあまり理解できてないのですが, segmentation faultがでてないってことはメモリリークではないとは思うんですが, どうなんでしょう...
tiitoi

2018/10/02 14:25

代入の直前で valuepattern の中身を確認して、代入の直後で `CS[j].a` を確認してください。 回答に追記しましたが、std::vector の代入はコピー元の各値がコピーされますので、コピー元が空でなければ、空にならないはずです。 segmentation fault が起こらなくても、メモリの不正アクセスなどは起きている可能性があります。(segmentation fault が起こらないから大丈夫ということにはなりません。)
rosbergf1

2018/10/02 16:25

valuepatternは空じゃなかったので, メモリの関係ですかね... vectorの数を増やしすぎると, エラーを吐かずにおかしな挙動を示すみたいなことってあるんでしょうか?
tiitoi

2018/10/02 17:41

自分は vector の代入でおかしなことになった経験はないです。 ただ代入時に値コピーが行われる以上、メモリは追加で確保されます。メモリが逼迫するほど巨大なデータを扱っているのでしょうか? あと可能性としてですが、別のスレッドからこの関数で使われている変数にアクセスしたりしていないですよね?
rosbergf1

2018/10/02 18:04

回答有り難うございます. 実は, CS_BPTTという関数でものすごい量のvectorを扱っています. 試しに, CS_BPTTのところだけコメントアウトして実行してみたところ, おかしなことになることはなくなりました. この関数をできるだけメモリを使わないように動作するように改良したいと思います. ありがとうございました.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問