dbgheap.c генерирует исключение нарушения прав доступа

Я разработал следующий кусок кода, который работает хорошо:

#include "header.h"
int test_DGGEV_11_14a(){
const int n=3;
double a[n][n]={1,1,1,2,3,4,3,5,2};
double b[n][n]={-10,-3,12,14,14,12,16,16,18};
//double a[n][n]={1,7,3,2,9,12,5,22,7};
//double b[n][n]={1,7,3,2,9,12,5,22,7};

/*const int n=2;
double a[n][n]={1e-16,0,0,1e-15};
double b[n][n]={1e-16,0,0,1e-15};*/

lapack_int info;
double alphar[n]={0.0};
double alphai[n]={0.0};
double beta[n]={0.0};
double vl[n][n]={0.0};
double vr[n][n]={0.0};

info=LAPACKE_dggev(LAPACK_ROW_MAJOR,'V','V',n,*a,n,*b,n,alphar,alphai,beta,*vl,n,*vr,n);

std::cout<<"right eigen vector (what we want):\n";
for(int i=int(0);i<n;i++){
for(int j=int(0);j<n;j++){
printf("%1f ",vr[i][j]);
}
printf("\n");
}
std::cout<<"left eigen vector:\n";
for(int i=int(0);i<n;i++){
for(int j=int(0);j<n;j++){
printf("%1f ",vl[i][j]);
}
printf("\n");
}
std::cout<<"eigen values:\n";
for(int i=int(0);i<n;i++){
if(beta[i]>DBL_MIN || beta[i]<-DBL_MIN){
printf("%1f ",alphar[i]/beta[i]);
printf("\n");
}else{
printf("%1f ","beta is zero");
printf("\n");
}
}
return info;
}

Я изменил приведенный выше правильный код, чтобы использовать процедуру LAPACKE DGGEV для большие матрицы, модифицированный код показан ниже:

#include "header.h"
int test_DGGEV_11_17a(){
const int r=342;
const int c=342;
double**a=NULL;//stiffness
a=new double *[r];
for(int i=int(0);i<r;i++)
a[i]=new double[c];
readFile("Input_Files/OUTPUT_sub_2_stiffness.txt",a,r,c);
writeFile("Output_Files/K.txt",a,r,c);//to check if readFile was OK

double**b=NULL;//mass
b=new double*[r];
for(int i=int(0);i<r;i++)
b[i]=new double[c];
readFile("Input_Files/OUTPUT_sub_2_mass.txt",b,r,c);
writeFile("Output_Files/M.txt",b,r,c);//to check if readFile was OK

const int n=r;//r=c=n
lapack_int info=110;
double alphar[n]={0.0};
double alphai[n]={0.0};
double beta[n]={0.0};
//double vl[n][n]={0.0};//generates stack overflow
double**vl=NULL;
vl=new double*[r];
for(int i=int(0);i<r;i++)
vl[i]=new double[c];
for(int i=int(0);i<r;i++)
for(int j=int(0);j<c;j++)
vl[i][j]=0.0;
//double vr[n][n]={0.0};//generates stack overflow
double**vr=NULL;
vr=new double*[r];
for(int i=int(0);i<r;i++)
vr[i]=new double[c];
for(int i=int(0);i<r;i++)
for(int j=int(0);j<c;j++)
vr[i][j]=0.0;

info=LAPACKE_dggev(LAPACK_ROW_MAJOR,'V','V',n,*a,n,*b,n,alphar,alphai,beta,*vl,n,*vr,n);

return info;
}

В приведенном выше модифицированном коде (для больших матриц) я должен выделить память из кучи, потому что в противном случае стек получит переполнение. Проблема в том, что когда я выделяю память из кучи new Я получаю следующее исключение, которое связано с кучей и происходит внутри dbgheap.c (Отладка функций кучи CRT):

введите описание изображения здесь

Кто-нибудь знает, почему происходит это исключение? может быть, это связано с тем, что библиотеки LAPACKE используют другую кучу для распределений … Я не знаю.


РЕДАКТИРОВАТЬ:

трассировка стека такова:

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь


РЕДАКТИРОВАТЬ:

в заключение решена проблема путем замены всех двумерных массивов на одномерные. Следующий код является исправленным кодом, который работает без каких-либо ошибок. Пожалуйста, смотрите ответ «Илья Кобелевский» для деталей этого решения.

int test_DGGEV_11_18a(){
const int r=342;
const int c=342;
double*a=NULL;//stiffness
a=new double [r*c];
for(int i=int(0);i<r*c;i++)
a[i]=0.0;
readFile_1Darray("Input_Files/OUTPUT_sub_2_stiffness.txt",a,r,c);
writeFile_1Darray("Output_Files/K.txt",a,r,c);//to check if readFile was OK

double*b=NULL;//mass
b=new double[r*c];
for(int i=int(0);i<r*c;i++)
b[i]=0.0;
readFile_1Darray("Input_Files/OUTPUT_sub_2_mass.txt",b,r,c);
writeFile_1Darray("Output_Files/M.txt",b,r,c);//to check if readFile was OK

const int n=r;//r=c=n
lapack_int info=110;

//double alphar[n]={0.0};
double*alphar=NULL;
alphar=new double[n];
for(int i=int(0);i<n;i++)
alphar[i]=0.0;
//double alphai[n]={0.0};
double*alphai=NULL;
alphai=new double[n];
for(int i=int(0);i<n;i++)
alphai[i]=0.0;
//double beta[n]={0.0};
double*beta=NULL;
beta=new double[n];
for(int i=int(0);i++;)
beta[i]=0.0;
//double vl[n][n]={0.0};//generates stack overflow
double*vl=NULL;
vl=new double[r*c];
for(int i=int(0);i<r*c;i++)
vl[i]=0.0;
//double vr[n][n]={0.0};//generates stack overflow
double*vr=NULL;
vr=new double[r*c];
for(int i=int(0);i<r*c;i++)
vr[i]=0.0;

info=LAPACKE_dggev(LAPACK_ROW_MAJOR,'V','V',n,a,n,b,n,alphar,alphai,beta,vl,n,vr,n);
std::cout<<"info returned by LAPACKE_dggev:\t"<<info<<'\n';

double*eigValueReal=NULL;
eigValueReal=new double[n];
for(int i=int(0);i<n;i++)
eigValueReal[i]=0.0;
for(int i=int(0);i<n;i++)
eigValueReal[i]=alphar[i]/beta[i];

write1Darray("Output_Files/eigValueReal_LAPACKE_DGGEV.txt",eigValueReal,n);
write1Darray("Output_Files/beta.txt",beta,n);
writeFile_1Darray("Output_Files/eigVectorRight_LAPACKE_DGGEV.txt",vr,r,c);

delete[] a;
delete[] b;
delete[] alphar;
delete[] alphai;
delete[] beta;
delete[] vl;
delete[] vr;
delete[] eigValueReal;

return info;
}

0

Решение

В соответствии с документация
LAPACKE_dggev ожидает double * в качестве входных данных, поэтому все матрицы должны храниться в виде линейных массивов.

Вместо

double**a=NULL;//stiffness
a=new double *[r];
for(int i=int(0);i<r;i++)
a[i]=new double[c];

Вы должны использовать

double*a=new double[c*r];//stiffness

С аналогичными изменениями для всех других матриц. Матричные элементы могут быть доступны как [i * c + j] для a [i, j]. Теперь могут быть другие проблемы с вашим кодом, но это очевидная проблема, которая может привести к появившейся ошибке.

1

Другие решения


По вопросам рекламы [email protected]