C ++ - 无法从函数返回向量

时间:2016-06-24 08:33:06

标签: c++ function vector return

假设以下功能

std::vector<double> LocatePulseEdges(int points, double* signal_x, double* signal_y, double threshold, vector<double> left_edge, vector<double> right_edge){
cout << "1" << endl;
    for (int i=0; i<points; i++){
        if(signal_y[i]<threshold){// left side of the pulse
            left_edge.push_back(signal_x[i]);
            break;
        }
        if(signal_y[i]>threshold){// right side of the pulse
            right_edge.push_back(signal_x[i]);
            break;
        }
    }
cout << "6" << endl;
    return left_edge;
    //return right_edge;

cout << "7" << endl;
}

我在以下代码中调用此函数

void Analyze(){
    int points = 90000000;//hSignal->GetNbinsX();
    double* x          = new double[points];           // SIZE limited only by OS/Hardware
    double* y          = new double[points];
    std::vector<double> left;
    std::vector<double> right;
    double threshold = 6234.34;

    Function_to_Fill_X_and_Y();
    LocatePulseEdges(points, x, y, threshold, left, right);
    cout << "First left threshold crossing @ time : " << left[0] << endl;
}

虽然我没有编译错误,但是当我运行程序时,它在return语句之前崩溃。

有关为何发生这种情况的任何想法?

3 个答案:

答案 0 :(得分:1)

通过引用传递left_edge,以便可以通过您的功能进行修改:

void LocatePulseEdges((int points, double* signal_x, double* signal_y, double threshold, 
std::vector<double> &left_edge, std::vector<double> &right_edge)
{
    //do your stuff
}

当你给出没有&的参数时,程序会复制你的参数的值,然后使用它。所以你无法修改它。使用&传递参数称为按引用传递。

当您通过引用传递对象时,您可以对其进行修改,并且速度更快。如果您需要传递一个对象而不修改它,请给出一个const ref:

void foo(const std::vector<double> &vec)

void foo(std::vector<double> vec)

并且由于vec关键字,您无法修改const

附加说明:

void函数不需要任何返回,但在许多情况下,它更好地执行Bool函数

Bool LocatePulseEdges()
{
    //do your stuff
    return True ;
}

如果出现任何问题,以这种方式进行此操作可以使您返回False。

答案 1 :(得分:1)

根据评论我得到了:

  1. 更改LocatePulseEdges函数以使用对:

    的引用

    void LocatePulseEdges((int points, double* signal_x, double* signal_y, double threshold, std::vector<double> &left_edge, std::vector<double> &right_edge) { //do your stuff } 因此,您可以更改函数

  2. 中的参数值
  3. 在访问元素之前检查元素是否存在:

    if (left.size() <= index) { return left[index]; }

  4. 现在您的代码出了什么问题。 for (int i=0; i<points; i++)已执行,因为points = 9000000,但signal_y[i]<threshold永远不会为真(在您的代码中未对其进行初始化),因此不会向left插入任何内容。

    < / LI>

答案 2 :(得分:1)

LocatePulseEdges函数以及Analyze函数存在一些缺陷。

首先,如果您要在代码的一个部分中使用std::vector<double>,为什么不在整个过程中使用它?你有:

void Analyze()
{
  //...        
  double* x = new double[points]; 
  double* y = new double[points];
 //...
}

除非您已调用delete [] xdelete [] y,否则此函数会发生内存泄漏。你可以简单地使用

std::vector<double> x(points), y(points);

并在填充它们的函数中,如果使用C ++ 11,则传递x.data()y.data(),如果不是,则传递&x[0]&y[0]。这减轻了内存泄漏。

即使您确实在某处有delete [],如果抛出异常,可能会绕过delete [],从而导致泄漏。使用std::vector即使异常也会销毁vector

其次,对于LocatePulseEdges函数,通过(const)引用传递向量,而不是按值传递。此外,不需要按值返回向量。如果你在函数中创建一个全新的向量,那么可能会证明返回新向量是合理的,但你不是这样做的。所以请返回void

void LocatePulseEdges(int points, double* signal_x, double* signal_y, double threshold, vector<double>& left_edge, vector<double>& right_edge)
{
    //...
}

当您按值传递向量时,会生成向量的副本,因此您left_edge.push_back()调用正在使用临时,而不是使用您传递的实际向量。这就是为什么返回时,向量left_edge是空的。

最后,如果您要访问向量中的第一项,请检查vector::empty()。您不能只假设该项存在于向量中。

   LocatePulseEdges(points, x.data(), y.data(), threshold, left, right);
   if ( !left.empty() ) 
       cout << "First left threshold crossing @ time : " << left[0] << endl;
   else
       cout << "No threshold's generated" << endl; 

上面的代码假设您接受了std::vector<double>x变量使用y的建议。