STATUS_ACCESS_VIOLATION in C++

STATUS_ACCESS_VIOLATION in C++

本文关键字:C++ in ACCESS STATUS VIOLATION      更新时间:2023-10-16

这是我的代码。当我不使用"POPSELF"数组时,它正确运行。但当我使用它时,我收到以下错误:' 47 [main] QCL 1581244 open_stackdumpfile: dump stack trace to QCL.exe.stackdump '

为什么给我这样的错误?

 // Declaring functions
 void license(); void Hamiltonian(double**,double*,double*,double*,double*,int,double&);
 void NEGF(complex<double>****,double**,double*,
        double*,double*,double*,double&,int,int,int,double,double);
// Global Variables
int main() {
    license();
    int n_Z ,n_E , n_K; double _Volt , _Temp ;
    GetParams Init ;  // Set Input Parameters
    Init.SetParams() ;
    n_Z = Init.Get_nZ() ;
    n_E = Init.Get_nE() ;
    n_K = Init.Get_nK() ;
    _Volt = Init.Get_Volt() ;
    _Temp = Init.Get_Temp() ;

    int ii=0 ,kk=0 ,xx=0; double *EnergyX ; double *PeriodX ;
    double *mstar; double *deltaU; double **Ham0;
    double *EpsDC; double *EpsAC; double dZ=0; ;
    EnergyX = new double [n_E] ; PeriodX = new double [n_Z];
    mstar = new double [n_Z] ; EpsDC = new double [n_Z];
    deltaU = new double [n_Z] ; EpsAC = new double [n_Z];
    Ham0 = new double *[n_Z];
    for(ii = 0; ii <n_Z; ii++)
    Ham0[ii] = new double[n_Z];
    Hamiltonian(Ham0,mstar,deltaU,EpsDC,EpsAC,n_Z,dZ) ;
    // NEGF
    complex<double> ****Gn= new complex<double> ***[n_Z];
    complex<double> ****POPSELF= new complex<double> ***[n_Z];
    for(ii=0;ii<n_Z;ii++)
        Gn[ii] = new complex<double> **[n_Z] ;
        POPSELF[ii] = new complex<double> **[n_Z] ;
        for(ii=0;ii<n_Z;ii++){
            for(kk=0;kk<n_Z;kk++){
                Gn[ii][kk] = new complex<double> *[n_K] ;
                POPSELF[ii][kk] = new complex<double> *[n_K] ;
            }
        }
        for(ii=0;ii<n_Z;ii++){
            for(kk=0;kk<n_Z;kk++){
                for(xx=0;xx<n_K;xx++){
                    Gn[ii][kk][xx]= new complex<double> [n_E] ;
                    POPSELF[ii][kk][xx]= new complex<double> [n_E] ;
                }
            }
        }
        NEGF(Gn,Ham0,mstar,EnergyX,PeriodX,deltaU,dZ,n_K,n_E,n_Z,_Volt,_Temp) ;
    return 0;
}

我想建议一个更好的方式来声明和使用4D数组:

std::vector< complex<double> > POPSELF(n_Z*n_Z*n_K*n_E);

或至少:

complex<double> *POPSELF = new complex<double> [n_Z*n_Z*n_K*n_E];

则,i,j,k,l是各自的索引,你用

来指代这些元素:
POPSELF[l + k*n_E + j*n_E*n_K + i*n_E*n_K*n_Z ]

有点长,但在c++中你可以将这些东西封装在Matrix4D类中并定义operator()为:

complex<double> &operator()(int i, int j, int k, int l) {
    return POPSELF[l + k*n_E + j*n_E*n_K + i*n_E*n_K*n_Z ];
}

这是在科学计算中处理动态多维矩阵时的正确方法,也更有效-比数组的数组更友好。(数组的数组!)关于缓存和预取。

最后我不得不说我在你的代码中发现了一个错误,但它会导致一个大的内存泄漏,而不是我认为的分段错误:ii上的for循环是重复嵌套的,要重新分配ii次所有数组的数组从第二层,但只保留对最后一个的引用。