PDA

View Full Version : Dynamic Memory Allocation in C++



Shawn Curry
10-05-2002, 08:32 AM
I'm trying to implement a long math data type in MSVC++. It(is supposed to)store a number as an array of char intead of bytes. In this fashion I thought I could write new math functions that model long-hand math, so the type could precisely compute extremely large numbers(limited only by the amount of addressable memory). It contains a
char* and an
int (for strlen). Im in the process of overloading the operators so i can implement it like a standard data type. I have <,>,= up and running, and im trying to implement operator+. I have to allocate a new string to hold the output data, but when I declare a new object inside the function, it throws an exception. Also, when I declare a
new char[num]num is longer than it's supposed to be. Also, the destructor throws an exeption if i try to delete the string I allocated in the constructor. Im a first year student, so im sure im doing something wrong, but I dont know what. Im uploading the code in a .txt(I truncated a lot of it and its down around 278, still way to big to post in this window)
The operator+ is kinda sloppy (Ive been testing the %#* out of it, sorry)

maes
10-05-2002, 10:17 AM
When you delete your array, did you do it like this:


char *output
...
output=new char[num];
...
delete []output;



That is the only hing I can come up with :(


Is it possible to cut the txt file in two and upload it in two posts?

Shawn Curry
10-05-2002, 10:31 AM
Hmm.. I tried to u/l it as a text file.. guess it didn't work. My first concern is why the new char[length] is giving me an array of the wrong length. I'm thinking its something to do with the copy/assignment constructor & the fact that they're not freeing the memory right.

Here's the first half:


#include <iostream>
#include <cstring>
#include <cmath>


//--- Global Functions
int convertbit(char in);
char convertbit(int in);
bool againyn();
//---

class LongMath
{
public:

char* string;
int length;

public:


LongMath()
{
length = 0;
string = new char[0];
//std::cout << "\nDefault Constructor called";
}

LongMath(int len)
{
this->length = len;

if(this->string)
{
std::cout << "\nData present in member string during constructor call";
//std::cout << this->string;// << '\n' << strlen(this->string);
//delete [] this->string;
}

this->string = new char[len];
std::cout << "\nstrlen(this->string): " << strlen(this->string);
}

LongMath(char* str)
{
this->length = strlen(str);

if(this->string)
{
//delete [] string;
}

this->string = new char[this->length];
strcpy(string, str);
}
///*
LongMath(LongMath& lm)
{
//std::cout << "\nCopy Constructor\n";
if(this->string)
{
//delete [] string;
}
this->string = new char[lm.length];
strcpy(this->string, lm.string);
this->length = lm.length;
}
//--- */
~LongMath()
{

if(this->string)
{
//std::cout << "\nDestructor found data in member string: ";
//std::cout << this->string;
//delete [] string;
}
}

public:

bool operator>(const LongMath& a)
{
if(this->length != a.length)
return this->length > a.length;
else
{
int index = 0;
while(index != (this->length))
{
if( (convertbit(this->string[index])) > (convertbit(a.string[index])) )
return true;
else if( (convertbit(this->string[index])) < (convertbit(a.string[index])) )
return false;
else
index++;
}
return false;//numbers are equal at this point
}
}

public:

bool operator<(const LongMath& a)
{
if(this->length != a.length)
return this->length < a.length;
else
{
int index = 0;
while(index != this->length)
{
if( ( convertbit(this->string[index]) ) < ( convertbit(a.string[index])) )
return true;
else if( (convertbit(this->string[index])) > (convertbit(a.string[index])) )
return false;
else
index++;
}
return false;
}
}

public:

LongMath& operator=(const LongMath& a)
{
if(this->string)
{
//std::cout << "Data present in this->string before assignment: " << this->string;
//delete [] string;
}
string = new char[a.length];
strcpy(this->string, a.string);
this->length = a.length;
return *this;
}

public:

LongMath operator+(const LongMath& a)
{
int len1 = this->length;
//std::cout << "\nthis->length = " << strlen(this->string);
int len2 = a.length;

CONTINUED NEXT POST

Shawn Curry
10-05-2002, 10:39 AM
I've rewritten and tested this part DOZENS of times, I left my little testers in there... Eventually I'm going to make a class hierarchy to orgainize all this better(instead of all in the same class) but it was way easier to test it when its all in the same class.
The operator+ has the pieces it needs to do what its intended to do, but I cant get the new char[string] to be the right length, so its left unfinished. It compiles, but I get runtime errors when I change anything from this point. Maybe you can suggest something I havent tried yet.
Gets a little sloppy here:


//std::cout << "\na.length = " << strlen(a.string);
int accum = 0;
bool remainder = false;
LongMath big;//(this->length);
LongMath small;//(a.length);
int larger;

if(*this > a )
{
//---- PRETTY MUCH THIS WHOLE BLOCK IS TESTS
// /*---All it REALLY NEEDS to do is allocate 1 or 2 strings the
proper length
//^---REMOVE THAT C++ STYLE COMMENT TO COMMENT THE WHOLE BLOCK
larger = len1+1;
//std::cout << "larger:" << larger;

if(big.string){
//std::cout << '\n' << strlen(big.string);
//std::cout << "\nData Deleted from big.string: " << big.string;
delete [] big.string;
}

big.string = new char[larger];
big.length = strlen(big.string);
//std::cout << "\nbig.string: " << big.string;
//std::cout << "\nbig.length = " << strlen(big.string) << " or " << big.length;
if(small.string){
std::cout << "\nsmall.length before delete: " << strlen(small.string);
std::cout << "\nData Deleted from small.string: " << small.string;
delete [] small.string;
}
small.string = new char[len1];
//std::cout << "\nsmall.string: " << small.string;
small.length = strlen(small.string);
//std::cout << "\nsmall.length = " << small.length << " or " << strlen(small.string);
//----ALL THE WAY TO HERE */
while(len1 >= 0)
{
remainder = addit(remainder, accum, big.string[len1+1],
convertbit(this->string[len1]), convertbit(a.string[len2]));
len1--;
len2--;

}
// /*-------GROSSLY UNFINISHED

}
else
{
//big.string = new char[len2+1];
//big.length = (len2 + 1);
small.string = new char[len2];
small.length = len2;

}
return small;
}

public: // Package with addition class

// RETURNS THE REMAINDER EX: remainder = andcarry(accum, out[last])

bool andcarry(int acc, char& write)
{
if(acc > 9)
{
acc = (acc - 10);
write = convertbit(acc);
return true;
}
else
{
write = convertbit(acc);
return false;
}
}

bool addit(bool rem, int& accu, char& towrite, int fst = 0, int lst = 0)
{
if(rem)
{
accu = ( (fst + lst) + 1 );
rem = andcarry(accu, towrite);
return rem;
}
else
{
accu = ( fst + lst );
rem = andcarry(accu, towrite);
return rem;
}
}
};

int main()
{
do {

LongMath first("1000");
LongMath next("999");
LongMath last;
last = first + next;
//std::cout << '\n' << first.string << "\n+" << next.string;
//std::cout << "\n-----\n" << last.string;

}while(againyn());

return 0;
}

bool againyn()
{
char input;
std::cout << "\nAgain? (y/n): ";
std::cin >> input;
if ( (input == 'y') || (input == 'Y') )
return true;
else
return false;
}

int convertbit(char in)
{
int output = (in - 48);
return output;
}

char convertbit(int in)
{
if(in > 0)
{
char output = (in + 48);
return output;
}
else
return '!';
}