mokk
mokk

Reputation: 33

Double Free or Corrupt Error

Can anyone help me figure out why I have a runtime error in my code when using gnuWin32. The error disappers when the GaussSeidel function is commented. I tried the online GNU GCC v4.8.3 compiler and it seems to work fine there. C++14 on ideone.com gave me the runtime error double free or corruption. I attached a simple version of my code which suffers from that error. Thanks.

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

Upvotes: 3

Views: 164

Answers (2)

Rob
Rob

Reputation: 1974

I can identify a possible contributor.

ynew and yold are both dynamically allocated arrays of a basic type (double). The first action within the function is to assign yold[i] = ynew[i] in a loop (where i runs from zero to nn-1)

The problem is that operator new default-initialises the elements of the array. Default initialisation of basic types (double, int, pointers, etc) actually leaves them uninitialised (except in a couple of special case, such as statics, when they are zero-initialised).

As assignment of the form "x = y" does what is called an rvalue-to-lvalue conversion on y (a complicated way of saying "access the value of y so x can be assigned the same value"). An rvalue-to-lvalue conversion has undefined behaviour on an uninitialised variable.

In short: after dynamically allocating your arrays within GaussSeidel() you need to initialise them before accessing values of elements.

On a quick skim, I haven't picked up any other obvious concerns that would involve undefined behaviour.

Rather than monkeying around directly with operators new and delete, I also suggest considering use of std::vector.

Upvotes: 0

Leeor
Leeor

Reputation: 19706

Your last loop inside the function uses i as an index, which at this point probably equals nn and is out of bounds. You probably meant to use the loop variable j.

As a result, you access out of the xvec array range, which is undefined behavior and probably corrupt one of the other internally defined arrays prior to deleting it

Upvotes: 4

Related Questions