假设以下功能
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语句之前崩溃。
有关为何发生这种情况的任何想法?
答案 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)
根据评论我得到了:
更改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
}
因此,您可以更改函数
在访问元素之前检查元素是否存在:
if (left.size() <= index)
{
return left[index];
}
现在您的代码出了什么问题。 for (int i=0; i<points; i++)
已执行,因为points = 9000000
,但signal_y[i]<threshold
永远不会为真(在您的代码中未对其进行初始化),因此不会向left
插入任何内容。
答案 2 :(得分:1)
LocatePulseEdges
函数以及Analyze
函数存在一些缺陷。
首先,如果您要在代码的一个部分中使用std::vector<double>
,为什么不在整个过程中使用它?你有:
void Analyze()
{
//...
double* x = new double[points];
double* y = new double[points];
//...
}
除非您已调用delete [] x
和delete [] 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
的建议。