【问题标题】:Average Large Array平均大数组
【发布时间】:2013-03-13 23:36:33
【问题描述】:

我正在尝试平均一个大的(~1.000.000 数据集)向量。我已经有了这样的数据:

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

现在我想平均一天的所有值。时间戳是这样的:“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);
}

这给了我一个邪恶的例外(邪恶的例外=分段违规)。我只是无法理解这件事。 最好和最快的方法是什么?

【问题讨论】:

  • “这给了我一个邪恶的例外” - 是吗?我不知道std::evil_exception。有趣的。如何发布实际错误及其发生位置?
  • 什么邪恶的异常?从哪条线?到目前为止你做了哪些调试?
  • 您正在返回对本地对象的引用...
  • 这个问题不清楚;你使用加载的短语(比如“显然”,当它真的不是那种东西时,或者“邪恶”而不描述你的实际意思),只是假设每个人都知道你所说的“平均”是什么意思。把问题弄清楚,目前还无法回答,而且你的代码更多的是混淆而不是帮助(例如,为什么它按值获取参数并返回一个悬空的右值引用?)。哦,是的,而且 1M 实际上也没有那么大。
  • 不返回std::move;它会干扰编译器的内置优化

标签: c++ arrays vector average


【解决方案1】:

您的程序很可能有未定义行为。无论是什么导致您遇到的异常,这里:

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

您正在返回对本地对象的引用。当接收到这个返回引用的变量被赋值时,这个引用的对象将因为超出范围而死掉。

因此,您基本上是在返回一个悬空引用,并且取消引用会将未定义的行为注入您的程序。

以这种方式返回您的对象(请注意,您可能希望按引用而不是按值传递包含一百万个条目的向量!):

    days average_days(const std::vector<data>& _d)
//  ^^^^                                     ^ 
//  No rvalue reference!             Pass by reference!
    {
        days ret;
        // ...
        return ret;
    //         ^^^
    //         No std::move()!
    }

【讨论】:

  • 刚刚试过:同样的事情。我认为是算法导致程序崩溃。
  • @BenediktWutzi:实际上我意识到这不应该是异常的原因,尽管感觉不正确。
  • 其实我也是这么想的。我用“if(!found)...”来处理这个问题
猜你喜欢
  • 2023-03-24
  • 1970-01-01
  • 2019-08-28
  • 1970-01-01
  • 1970-01-01
  • 2014-01-23
  • 2018-05-31
  • 2012-04-21
  • 1970-01-01
相关资源
最近更新 更多