Reputation: 33
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
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
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