-2

大きな(〜1.000.000データセット)ベクトルを平均化しようとしています。私はすでに次のようなデータを持っています:

struct data {
    std::string alias;
    double id;
    std::string timestamp;
    double value;
};

今、私は 1 日のすべての値を平均したいと考えています。タイムスタンプは「20-NOV-12 10.52.21.260000000 AM」のようなものです。日を表す文字列の一部を含む substr(0,8) だけを気にします。現在、私はこれを持っています:

typedef std::vector<std::tuple<std::string, size_t, double>> days; 
days&& average_days(const std::vector<data> _d)
{
  days ret;
  for(auto &d: _d) {
      bool found = false;
      int count = 0;
      double val= 0.0;
      for(size_t i = 0; i < ret.size(); i++) {
          std::string day = d.alias.substr(0,8);
          auto t = ret[i];
          if (std::get<0>(t) == day) {
             found = true;
             std::string ali = std::get<0>(t);
             size_t coun = std::get<1>(t) + 1;
             double val = std::get<2>(t) + d.value;
             ret[i] = std::make_tuple(ali, coun, val);
         }
         val = std::get<2>(t);
      }
      if (!found){
          ret.push_back(std::make_tuple(d.alias.substr(0,8) ,1, val));
      }
}
return std::move(ret);
}

これにより、邪悪な例外が発生します(邪悪な例外=セグメンテーション違反)。私はこのことについて頭を悩ませることができません。これを行う最善かつ最速の方法は何ですか?

4

1 に答える 1

5

あなたのプログラムにはUndefined Behaviorがある可能性が非常に高いです。あなたが経験している例外を引き起こしているものは何でも、ここに:

    days&& average_days(const std::vector<data> _d)
//  ^^^^^^
    {
        days ret;
        // ...
        return std::move(ret);
    }

ローカル オブジェクトへの参照を返しています。この返された参照を受け取る変数が割り当てられるまでに、この参照先がバインドされていたオブジェクトはスコープ外になるため、死んでしまいます。

したがって、基本的にダングリング参照を返し、未定義の動作をプログラムに挿入する逆参照を行っています。

オブジェクトを次のように返すだけです (そして、値ではなく参照によって、100 万個のエントリを持つベクトルを渡したいという事実に注意してください!):

    days average_days(const std::vector<data>& _d)
//  ^^^^                                     ^ 
//  No rvalue reference!             Pass by reference!
    {
        days ret;
        // ...
        return ret;
    //         ^^^
    //         No std::move()!
    }
于 2013-03-13T23:51:02.077 に答える