In my last post I mentioned that I was fixing a heap overflow and making speed improvements to the + function in ipfloat. Memory in C++ is stored in an interesting way. There are two main sections of memory that a programmer must worry about – the heap and the stack. (There is a global region of memory as well, but this doesn’t usually create problems, unless the program is designed poorly and data is not well encapsulated.)
The heap is “dynamic memory” – any dynamic variables get allocated in the heap. Essentially, anything created using new or malloc will get stored here. The stack is for local variables, parameters, and temporary variables (created during assignments/operations that are never explicitly created).
What was my problem? Heap overflow/corruption. This is what was happening:
Heap:
|-man-||–thisMan–||–rhsMan–|
thisMan and rhsMan were normalized with zero’s, so they became a little larger. But man must be expanded to hold the result of both of the other two, so if the difference between sizes of man and rhsMan was too great, man would overflow and corrupt thisMan. And since man was calculated from thisMan, _bad things_ would happen.
So, while 3.14159 + 2.18281 would cause no problems (man wouldn’t need to expand at all), and even something like 2.323123222312341 + 123123123.12312 would be okay, something like 0.00000000000000000001 + 123123123.123123123 would _at least_ corrupt data, if not overflow the heap altogether.
This is because 0.00000000000000000001 is actually stored in memory as [1, -20, +] and 123123123.123123123 is stored as [123123123123123123, 8, +]. This makes man=1, thisMan = 000000000000000000001, and rhsMan=123123123123123123. Man is stored _before_ thisMan, so in order to expand to fit all of the digits, it must of necessity overflow into thisMan.
How did I fix this? By completely restructuring, of course
This is how it works now:
Heap:
|–man–||–rhs–||—-result—-|
Now instead of copying man into a temporary variable and expanding man to hold the result, I make the temporary variable hold the result and its space is allocated _after_ the original values. No corruption!
I also reworked the addition algorithm (haven’t finished yet), to save some time. I’ll save that for another post, I’m now out of time.