C++ 双重自由或损坏错误

C++ 双重自由或损坏错误,c++,C++,有人能帮我找出为什么在使用gnuWin32时代码中出现运行时错误吗。注释GaussSeidel函数时,错误消失。我试过在线GNU GCC v4.8.3编译器,它似乎在那里工作得很好。ideone.com上的C++14给了我运行时错误double free或Corrupt。我附加了我的代码的一个简单版本,该版本存在该错误。谢谢 #include <iostream> #include <cmath> void GaussSeidel(double** const aa,

有人能帮我找出为什么在使用gnuWin32时代码中出现运行时错误吗。注释GaussSeidel函数时,错误消失。我试过在线GNU GCC v4.8.3编译器,它似乎在那里工作得很好。ideone.com上的C++14给了我运行时错误double free或Corrupt。我附加了我的代码的一个简单版本,该版本存在该错误。谢谢

#include <iostream>
#include <cmath>

void GaussSeidel(double** const aa, double* const bb, double* xvec, const int nn, int mm)
{
    int i = 0, j = 0;
    double *ynew=NULL, *yold=NULL, EE=20.0;
    ynew=new double[nn];
    yold=new double[nn];

    while (mm > 0 && EE>0.00001) {
        EE=0.0;
        for (i = 0; i < nn; i++) {
            yold[i]=ynew[i];
            ynew[i] = bb[i] / aa[i][i];
            for (j = 0; j < nn; j++) {
                if (j == i) continue;
                ynew[i] = ynew[i] - (aa[i][j] * xvec[j]/ aa[i][i]);
                xvec[i] = ynew[i];
            }
            if (std::abs(ynew[i]-yold[i])>EE) EE=std::abs(ynew[i]-yold[i]);
        }
        mm--;
    }
    std::cout << mm << "  " << EE << std::endl;

    for (j = 0; j < nn; j++)
        xvec[i] = ynew[i];

    delete [] ynew;
    delete [] yold;
}

int main (void)
{
    int i, j;
    const int Np=100;
    double **Infl=NULL, *Source=NULL, *FpdPhi0=NULL;

    Source=new double[Np];
    FpdPhi0=new double[Np];
    Infl  = new double *[Np]; for(i = 0; i < Np; i++) Infl[i] = new double[Np];

    for (j=0; j<Np; j++){
        for (i=0; i<Np; i++){
            if (i==j){
                Infl[j][i]=1.0;
            }
            else {
                Infl[j][i]=0.0;
            }
        }
        Source[j]=4.0;
        FpdPhi0[j]=0.1;
    }
    GaussSeidel(Infl, Source, FpdPhi0, Np, 300);

    for(i = 0; i < Np; i++) delete [] Infl[i];
    delete [] Infl;
    delete [] Source;
    delete [] FpdPhi0;

    return 0;
}
#包括
#包括
void Gausseidel(双**常数aa,双*常数bb,双*xvec,常数int nn,int mm)
{
int i=0,j=0;
double*ynew=NULL,*yold=NULL,EE=20.0;
ynew=新的双精度[nn];
yold=新的双精度[nn];
而(mm>0&&EE>0.00001){
EE=0.0;
对于(i=0;iEE)EE=std::abs(ynew[i]-yold[i]);
}
嗯--;
}

std::cout函数中的最后一个循环使用
i
作为索引,此时它可能等于
nn
,超出了范围。您可能打算使用循环变量
j


因此,您的访问超出了
xvec
数组范围,这是一种未定义的行为,可能会在删除其他内部定义的数组之前损坏该数组

我可以确定一个可能的贡献者

ynew和yold都是动态分配的基本类型数组(double)。函数中的第一个操作是在循环中分配yold[i]=ynew[i](其中我从零运行到nn-1)

问题是运算符new default初始化数组的元素。基本类型(double、int、指针等)的默认初始化实际上使它们未初始化(除非在一些特殊情况下,例如静态,当它们为零初始化时)

由于形式“x=y”的赋值在y上进行所谓的右值到左值的转换(这是一种表示“访问y的值以便可以为x赋值相同”的复杂方式)。右值到左值的转换在未初始化的变量上具有未定义的行为

简言之:在GausSeidel()中动态分配数组后,需要在访问元素值之前对其进行初始化

快速浏览一下,我还没有发现任何其他涉及未定义行为的明显问题


与其直接与运算符new和delete混在一起,我还建议考虑使用std::vector。

使用
std::vector
并摆脱所有毫无意义的手动内存管理。此外,如果第二次调用
new[],您的Gausseidel会出现内存泄漏
在该函数中引发异常。通过使用
std::vector
避免所有这些问题。限制for循环索引变量的范围是个好主意。感谢大家的回复。如果我使用vector类而不是指针,需要多少内存?必须更正确?我的问题是内存密集型的d我正在试图节省内存。@mokk不同之处在于每个向量的大小(std::vector)-sizeof(double*)
。谢谢你的回复。可以。