"Spine" <
XXXX@XXXXX.COM >writes:
Quote
this is what I have now: I have deleted as much code as posible, and still
the program will hang. In the main program I create an array of TNumber
using a pointer.
When you post code, though, it's helpful to always post enough that it
can be compiled and executed by a simple cut-and-paste. When you lave
out the class declaration, main(), and other parts of the prgram that
actually make use of the code, it's impossible to see the full
problem, or reproduce it ourselves;
Quote
(->could this be the problem? ) this works fine until at a
Anything could be a problem. Working with pointers is error-prone,
and since you are talking about accessing invalid memory, something is
clearly wrong.
Quote
certain point the programs stops running. somehow this always happens in the
TNumber TNumber::operator+(TNumber const &other), where I create the new
TNumber even. (changing even to something else that surely does not exist
does not help).
Hmmmm.
Quote
TNumber::TNumber()
{
Size = 10;
exp = 0;
sign=1;
Value = new int[Size];
for (int l=0;l<Size;l++) Value[l] = 0;
}
This constructor, like all constructors, would be better if it used
the initializer list whenever possible:
TNumber::TNumber()
: Size(10)
, exp(0)
, sign(1)
, Value(new int[Size])
{
memset( Value, '\0', Size * sizeof(Value[0]) );
}
Note very carefully that initializations are NOT done in the order of
the initializer list. The actual members are initialized in the order
they appear in the class declaration. Therefore, it is impererative
that you declare the member "Size" in your class before you declare
the Value array, or else this initialization won't work (since Value
is allocated in terms of Size, which obviously must be initialized
before it's used.)
I post this warning since the header isn't included, and I'm not going
to bother going back to old posts on the chance that what was posted
then is still the same today. (Another reason to include the
declarations in one post. A rule of thumb is: When posting code,
make it complete, and never use an #include for your own code. If the
file is self-sufficient to compile, then everyone can compile it
without having to have access to other files that may have not been
posted.)
Quote
TNumber& TNumber::operator=(TNumber const &other)
{
memcpy(Value,other.Value,other.Size * sizeof(int));
sign = other.sign;
exp = other.exp;
return *this;
}
This copy-assignment operator is still wrong. It is depending on the
fact that other's Size is the same, and will have undefined behavior
if the other's Size is larger. Do not depend on assumptions like
that, as it will eventually change. If the size must always be the
same amount for all instances, then it should not be a member
variable, and should be a constant value instead. (Such as an enum or
const static class member.)
Quote
TNumber& TNumber::operator=(double other)
{
if (other<0){
sign = -1;
other = -other;
}else sign = 1;
if (other!=0) exp = floor(log10(other));else exp=0;
AnsiString even = FloatToStr(other/pow(10,exp));
Value[0] = StrToFloat(even.SubString(1,1));
int tel=1;
while (tel<even.Length()-1){
Value[tel] = StrToInt(even.SubString(tel+2,1));
tel++;
}
for (int l=tel;l<Size;l++) Value[l]=0;
return *this;
}
Question: what is the max value that 'tel' can possibly have? How
does this code know that Value[tel] is actually indexing to a valid
value?
I see your for-loop more than once. Perhaps that indicates you should
have a member function named something like "zero_out_data()", which
factors out the implementation.
Quote
TNumber TNumber::operator+(TNumber const &other)
{
TNumber result = *this;
TNumber even;
return result;
}
Simply declaring even causes the problem? How about simply declaring
TNumber in main()... does that also have a problem?
Side note: the member functions like operator+ should be declared
"const" since they do not modify the current object.
I'm assuming the correctness of your operator+'s result is known to be
wrong, as you said you removed as much code as possible.
Quote
TNumber TNumber::operator+(double other)
{
TNumber result,even;
even = other;
double sipke = ToDouble();
result = *this + even;
sipke = ToDouble();
AnsiString sipke1 = ToStr();
return result;
}
There appears to be some useless work going on in here. For example,
there are no uses of sipke, yet it is assigned the result of ToDouble
twice, and sipke1 is also calculated but not used. Is this code
related to the problem, and you removed other lines of code that are
meaningful to the result but not related to the memory problem?
--
Chris (TeamB);