M
mike3
Hi.
I was writing a program in C++ that generates fractals. I got this
weird bug though right now that's holding it up and was wondering if
you could help.
Anyway, it seems that when this code is executed, it corrupts the
memory causing a crash later on (the program actually causes an
"access violation" error in Windows, which the program is running
under):
*WindowXStep_W /= (*Mag_W * (u32)2);
*WindowYStep_W /= (*Mag_W * (u32)2);
Here "WindowXStep_W", "Mag_W" are of a custom type called "BigFloat"
that contains a bignum implementation, with overloaded operators. I've
looked over all the calculation routines and can't find any reason
they would corrupt the memory. It seems to have something to do with
the use of operators that take two operands and then output one --
things like the multiplication above. When the code is changed to
*WindowXStep_W /= *Mag_W ;
*WindowYStep_W /= *Mag_W;
*WindowXStep_W /= (u32)2;
*WindowYStep_W /= (u32)2;
or even
*Mag_W *= (u32)2;
*WindowXStep_W /= *Mag_W;
*WindowYStep_W /= *Mag_W;
(which of cours secrews up Mag_W's value, but the change is for
debugging this specific problem.)
there's no problem. Similar problems seem to occur with any use of
operators that return a "BigFloat", like "*", "+", and "-", and not
"const BigFloat &" operators like "/=" and "*=" above. I even
"debased" them to remove the calculation guts and leave just "return
BigFloat(...)" at the end and still it crashes. I checked through
"EquateBF" which equates one BigFloat to another, and couldn't find
anyhting that would create a memory overflow or something.
Here's a few code snippets in case they might help:
/* Construct a BigFloat that is a copy of another. */
BigFloat::BigFloat(const BigFloat & bfValue)
{
FG3DError err;
/* Initialize */
err = this->Init(bfValue.length);
if(err.dwErrCode != FG3D_SUCCESS)
throw Exception(err);
/* Set to BigFloat */
err = this->EquateBF(&bfValue);
if(err.dwErrCode != FG3D_SUCCESS)
throw Exception(err);
/* Done! */
return;
}
(note: "u32" = "unsigned long")
BigFloat operator*(const BigFloat &a, u32 b)
{
FG3DError err;
BigFloat tmp = BigFloat((BOOL)FALSE, a.length);
/* Mul */
err = FG3DMPFloat_MulSmallU(&tmp, &a, b);
if(err.dwErrCode != FG3D_SUCCESS)
throw Exception(err);
/* Return result */
return(tmp);
}
/* Division operator: /= */
const BigFloat & BigFloat:perator/=(const BigFloat &a)
{
FG3DError err;
/* Div */
err = FG3DMPFloat_Div(this, this, &a);
if(err.dwErrCode != FG3D_SUCCESS)
throw Exception(err);
/* Return result */
return(*this);
}
I was writing a program in C++ that generates fractals. I got this
weird bug though right now that's holding it up and was wondering if
you could help.
Anyway, it seems that when this code is executed, it corrupts the
memory causing a crash later on (the program actually causes an
"access violation" error in Windows, which the program is running
under):
*WindowXStep_W /= (*Mag_W * (u32)2);
*WindowYStep_W /= (*Mag_W * (u32)2);
Here "WindowXStep_W", "Mag_W" are of a custom type called "BigFloat"
that contains a bignum implementation, with overloaded operators. I've
looked over all the calculation routines and can't find any reason
they would corrupt the memory. It seems to have something to do with
the use of operators that take two operands and then output one --
things like the multiplication above. When the code is changed to
*WindowXStep_W /= *Mag_W ;
*WindowYStep_W /= *Mag_W;
*WindowXStep_W /= (u32)2;
*WindowYStep_W /= (u32)2;
or even
*Mag_W *= (u32)2;
*WindowXStep_W /= *Mag_W;
*WindowYStep_W /= *Mag_W;
(which of cours secrews up Mag_W's value, but the change is for
debugging this specific problem.)
there's no problem. Similar problems seem to occur with any use of
operators that return a "BigFloat", like "*", "+", and "-", and not
"const BigFloat &" operators like "/=" and "*=" above. I even
"debased" them to remove the calculation guts and leave just "return
BigFloat(...)" at the end and still it crashes. I checked through
"EquateBF" which equates one BigFloat to another, and couldn't find
anyhting that would create a memory overflow or something.
Here's a few code snippets in case they might help:
/* Construct a BigFloat that is a copy of another. */
BigFloat::BigFloat(const BigFloat & bfValue)
{
FG3DError err;
/* Initialize */
err = this->Init(bfValue.length);
if(err.dwErrCode != FG3D_SUCCESS)
throw Exception(err);
/* Set to BigFloat */
err = this->EquateBF(&bfValue);
if(err.dwErrCode != FG3D_SUCCESS)
throw Exception(err);
/* Done! */
return;
}
(note: "u32" = "unsigned long")
BigFloat operator*(const BigFloat &a, u32 b)
{
FG3DError err;
BigFloat tmp = BigFloat((BOOL)FALSE, a.length);
/* Mul */
err = FG3DMPFloat_MulSmallU(&tmp, &a, b);
if(err.dwErrCode != FG3D_SUCCESS)
throw Exception(err);
/* Return result */
return(tmp);
}
/* Division operator: /= */
const BigFloat & BigFloat:perator/=(const BigFloat &a)
{
FG3DError err;
/* Div */
err = FG3DMPFloat_Div(this, this, &a);
if(err.dwErrCode != FG3D_SUCCESS)
throw Exception(err);
/* Return result */
return(*this);
}