C++ - 无法从函数返回向量
Posted
技术标签:
【中文标题】C++ - 无法从函数返回向量【英文标题】:C++ - Cannot return vector from function 【发布时间】:2016-06-24 08:33:06 【问题描述】:假设以下函数
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;
虽然我没有收到编译错误,但当我运行程序时,它会在返回语句之前崩溃。
知道为什么会这样吗?
【问题讨论】:
@Boiethios :嗯......我该如何检查?如果是这种情况,我该如何解决? 对不起,我猜不是这样。 @Thanos 为什么要按值传递向量? @GMichael :我还能做什么?我对指针不太熟悉...... :( @Thanos 阅读参考资料... 【参考方案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
函数,传递向量的(常量)引用,而不是值。此外,不需要按值返回向量。如果您在函数中创建一个全新的向量,那么这可能会证明返回新向量是合理的,但您没有这样做。所以返回一个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
变量的建议。
【讨论】:
【参考方案2】:通过引用传递您的 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。
【讨论】:
【参考方案3】:基于 cmets 我得到了:
更改 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
。
【讨论】:
以上是关于C++ - 无法从函数返回向量的主要内容,如果未能解决你的问题,请参考以下文章