简体   繁体   English

dbgheap.c引发访问冲突异常

[英]dbgheap.c throws access violation exception

I have developed the following piece of code which works good: 我开发了下面的代码,效果很好:

#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;
}

I modified the above correct code, to use LAPACKE DGGEV routine for large matrices , the modified code is shown below: 我修改了上面的正确代码,以对大型矩阵使用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;
}

In the above modified code (for large matrices), I have to allocate memory from heap because otherwise, stack would get overflow. 在上面修改的代码中(对于大型矩阵),我必须从堆中分配内存,因为否则,堆栈将溢出。 The problem is that when I allocate memory from heap by new I get the following exception which is related to heap and occurs inside dbgheap.c (Debug CRT Heap Functions): 问题是,当我通过new从堆中分配内存时,出现以下与堆相关的异常,该异常发生在dbgheap.c (调试CRT堆功能)内部:

在此处输入图片说明

Does anybody know why this exception happens? 有人知道为什么会发生这种异常吗? maybe it is related to the fact that LAPACKE DLLs are using a different heap for allocations...I don't know. 也许这与LAPACKE DLL使用不同的堆进行分配这一事实有关...我不知道。


EDIT: 编辑:

the stack trace is this: 堆栈跟踪是这样的:

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明


EDIT: 编辑:

Finally solved the problem by replacing all the 2D arrays with 1D arrays. 最终通过用1D数组替换所有2D数组解决了该问题。 The following code is the corrected code which works without any error. 以下代码是正确的代码,可以正常工作。 Please see answer of "Ilya Kobelevskiy" for the details of this solution. 有关此解决方案的详细信息,请参见“ Ilya Kobelevskiy”的答案。

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;
}

According to documentation LAPACKE_dggev expects double* as an input, so all matrices need to be stored as linear arrays. 根据文档, LAPACKE_dggev希望将double *作为输入,因此所有矩阵都需要存储为线性数组。

Instead of 代替

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

You should use 你应该用

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

With similar changes for all otehr matrices. 所有矩阵的变化都相似。 Matrix elements can be accessed as a[i*c+j] for a[i,j]. 矩阵元素可以作为a [i,j]的a [i * c + j]访问。 Now, there might be other problems with your code, but this is an obvious one that may lead to the error you are seeing. 现在,您的代码可能还有其他问题,但这是一个显而易见的问题,可能会导致您看到错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM