我有一个带有一个变量数据类型template <class outputT>
的模板类。
在课堂上我有私有变量vector< outputT > outputData
。
因此,outputT
应为complex<double>
或vector< complex<double> >
。我有一个构造函数,其中一个参数是int N
给出outputData
向量的大小。在这个构造函数中,我像这样初始化outputData
:
ouputData.resize(N);
当我使用选项complex<double>
创建类的实例时,一切都很好。
但是如果我使用选项vector< complex<double> >
创建一个实例并尝试调用o outputData
的元素(来自公共函数getOutpuData()
),它会给我segmentation fault
。显然数据的内存存储有问题,但它是什么?
此外,当vector< complex<double> >
用于模板时,此类型的输入向量的大小为2。
我想我的初始化ouputData.resize(N);
不正确但不确定!
好的,这是我的班级:
template <class inputT, class outputT>
class LubichInverse {
public:
LubichInverse(inputT (*fofs_In)(complex<double>), double R_In,
double dt_In, int N_In, int L_In, int M_In = 1):
fofs(fofs_In), R(R_In), dt(dt_In), N(N_In), L(L_In), M(M_In) {
outputData.resize(N);
}
void calculateInverse() {
// do some stuff here to calculate outputData, e.g.:
for( int n=0; n<N; n++) {
complex<double> s( n, 2.0*n );
outputData[n] = fofs(s); // this one could be a source of memory bug!
}
}
vector< outputT > getOutputData() {
return outputData;
}
private:
inputT (*fofs)(complex<double>);
vector< outputT > outputData;
double R;
double dt;
int N;
int L;
int M;
};
这是实施:
// this is a function to test the complex<double> version
complex<double> testScalar(complex<double> s_In) {
return (1.0/(s_In-3.75));
}
// this is a function to test the vector< complex<double> > version
vector< complex<double> > testVector(complex<double> s_In) {
vector< complex<double> > tmp(2);
tmp[0] = 1.0/s_In;
tmp[1] = 1.0/(s_In-3.75);
return tmp; // Probably this one returns dangling pointer, namely tmp?
}
int main() {
// this one works fine!
LubichInverse< complex<double>, complex<double> > tmp_01(testScalar, 0.32, 0.001, 1000, 1000);
tmp_01.calculateInverse();
vector< complex<double> > vec_01(tmp_01.getOutputData());
cout << vec_01[2] << endl;
// this one is the problem
LubichInverse< vector< complex<double> >, vector< complex<double> > > tmp_02(testVector, 0.32, 0.001, 1000, 1000);
tmp_02.calculateInverse();
vector< vector< complex<double> > > vec_02(tmp_02.getOutputData());
cout << vec_02[0][1] << endl; // namely here is the segmentation fault problem, if remove this line it does not complain!
return 0;
}
我在原始的calculateInverse()
函数中找到了错误
void calculateInverse() {
double tmp_00(pid2/L);
for( int n=0; n < N; n++) {
double tmp_01(-n*tmp_00);
double tmp_02(pow(R,-n)/L);
// initialize outputData for the case l=0, this one was the problem
// outputData[n] = fofs( BDF2(R/dt) ); // this one is correct
// for ( int l=1; l<L; l++ ) { // this one is correct
for( int l=0; l < L; l++) { // here in the case l=0 is the issue
complex<double> tmp_10(0.0,tmp_00*l);
complex<double> s( BDF2(R*exp(tmp_10)) / dt );
complex<double> tmp_11(0,tmp_01*l);
outputData[n] += (fofs(s)*exp(tmp_11)); // here the left argument
// of overloaded operator+= is a vector< complex<double> >
// as is initialized in the constructor (just a pointer to null, I think)
// while the right argument is a vector< complex<double> >
// with size 2. So it is like adding vectors with zero size and size 2.
}
outputData[n] *= (tmp_02/dt);
}
}
请原谅我没有提供原始功能,但是我需要解释过载操作符,除此之外我还没想到会出现问题。但是,谢谢,我认为更简单的测试对本地化问题非常有帮助。