我正在使用QtCreator来编码一个已经在Matlab上编码的算法。
在编写这个程序时,我有两个错误。第一个(APPCRASH)只在我正常构建和执行程序时出现,但在我尝试调试它(Heisenbug)时不会出现,它出现在函数"matrixA"上。我试图让变量变得不稳定,并在其他函数上写矩阵A项公式,希望这能停止编译器优化(我认为编译器优化可能会导致问题),但我一直未能解决问题。我没有尝试使用选项-o编译项目,因为我的教授(这是一个大学项目)必须能够正常编译(没有特定选项)。
第二个是SISSEGV分割错误。当代码到达InpaintingColor上的"DestroyFloatArray(&b,width);"时,就会发生这种情况。
这里的代码:
clanu_process.cpp(有点乱,因为我尝试了很多东西…)
#include "clanu_process.h"
#include "iomanip"
void InpaintingColor(float **Rout, float **Gout, float **Bout, float **Rin, float **Gin, float **Bin, float **Mask, int width, int height, double param)
{
cout << "1" << endl;
float alphak = 0, bethak = 0, res = 0;
float **b = 0, **xk = 0, **dk = 0, **rk = 0, **Ark = 0, **tmp1 = 0,**tmp2 = 0,**tmp3 = 0;
Ark = AllocateFloatArray( width, height);
tmp1 = AllocateFloatArray( width, height);
tmp2 = AllocateFloatArray( width, height);
tmp3 = AllocateFloatArray( width, height);
xk = AllocateFloatArray( width, height);
dk = AllocateFloatArray( width, height);
rk = AllocateFloatArray( width, height);
b = AllocateFloatArray( width, height);
cout << "2" << endl;
res = 1e8;
matrixProductByScalar(b,1.0/(3.0*256),Rin,width,height);
matrixDuplicate(xk, b, width, height);
// APPCRASH error
matriceA(Ark,xk,Mask,width,height);
//More code
// SIGSEGV error
DestroyFloatArray(&b, width);
DestroyFloatArray(&xk, width);
DestroyFloatArray(&dk, width);
DestroyFloatArray(&rk, width);
DestroyFloatArray(&Ark, width);
DestroyFloatArray(&tmp1, width);
DestroyFloatArray(&tmp2, width);
DestroyFloatArray(&tmp3, width);
}
float** matriceA(float **A, float **I, float **Masque, int N2, int N1){
volatile bool bool_iplus = false, bool_imoins = false, bool_jmoins = false, bool_jplus = false;
volatile int iplus = 0, imoins = 0, jplus = 0, jmoins = 0;
for(int i = 1; i <= N1; i++){
bool_iplus = i<N1;
iplus = i+1 < N1 ? i+1 : N1;
bool_imoins = i>1;
imoins = i-1 > 1 ? i-1 : 1;
for(int j = 1; j <= N2; j++){
bool_jplus = j<N2;
jplus = j+1 < N2 ? j+1 : N2;
bool_jmoins = j>1;
jmoins = j -1 > 1 ? j-1 : 1;
if(Masque[i-1][j-1]!=0){
//cout << "if - " << i << ", " << j<< endl;
A[i-1][j-1] = (1.0/36)*(16*I[i-1][j-1]
+ 4*(
(bool_iplus?I[iplus-1][j-1]:0)
+ (bool_imoins?I[imoins-1][j-1]:0)
+ (bool_jplus?I[i-1][jplus-1]:0)
+ (bool_jmoins?I[i-1][jmoins-1]:0)
)+(
(bool_iplus&&bool_jplus?I[iplus-1][jplus-1]:0)
+ (bool_imoins&&bool_jplus?I[imoins-1][jplus-1]:0)
+ (bool_imoins&&bool_jmoins?I[imoins-1][jmoins-1]:0))
+ (bool_iplus&&bool_jmoins?I[iplus-1][jmoins-1]:0));
}else{
//cout << "else - " << i << ", " << j << endl;
A[i-1][j-1]=
-(1.0*N1*N2)*(
-8.0*I[i-1][j-1]
+ I[iplus-1][j-1]
+ I[imoins-1][j-1]
+ I[i-1][jplus-1]
+ I[i-1][jmoins-1]
+ I[iplus-1][jplus-1]
+ I[imoins-1][jplus-1]
+ I[imoins-1][jmoins-1]
+ I[iplus-1][jmoins-1]);
}
}
}
return A;
}
AllocateFloatArray和DestroyFloatArchy 函数
float ** AllocateFloatArray(int width, int height)
{
float ** r = new float*[width];
for(int i=0; i<width; i++)
r[i] = new float[height];
return r;
}
void DestroyFloatArray(float ***a, int width)
{
if( *a == 0 ) return;
for(int i=0; i<width; i++)
delete[] a[0][i];
delete[] *a;
*a = 0;
}
谢谢你抽出时间。
我不确定这是否是您问题的原因,但。。。
函数"矩阵运算"(sum()
、matrixSubstraction()
、matrixAddition()
、matrixProductByElement()
、matrixProductByScalar()
和matrixDuplicate()
)的范围是第一个索引从零到width
,第二个索引从0到height
。
如果我没有错的话,这是正确的,并且与分配/解除分配(AllocateFloatArray()
和DestroyFloatArray()
)一致。
但看看matriceA()
的两个函数;它们被定义为
float** matriceA(float **A, float **I, int N2, int N1)
float** matriceA(float **A, float **I, float **Masque, int N2, int N1)
在两个函数中,第一索引范围从零到N1
,第二索引范围从0到N2
;例如
for(int i = 1; i <= N1; i++){
// ...
for(int j = 1; j <= N2; j++){
// ...
A[i-1][j-1] = (1.0/36)*(16*I[i-1][j-1] // ...
很好。但是你用这种方式呼叫matriceA()
matriceA(Ark,rk,Mask,width,height);
简单地说:您将矩阵分配为width * height
矩阵;您的"矩阵运算"将它们用作width * height
矩阵,但您的matriceA()
函数将其用作height * width
。
摧毁记忆的绝妙方式。
我想解决方案可能是
1)matriceA()
定义中N1
和N2
的切换
2) 或者在matriceA()
中切换width
和height
呼叫
抱歉我英语不好。