我们刚刚在课堂上学习heap
,教授希望我们创建一个Rational
类型的数组,这只是一类带有运算符的Rational数字,如+ - * /已经超载。我的程序似乎工作,但最后崩溃,并给我一个错误。我认为这个错误与内存泄漏有关,但我不知道发生了什么。一些帮助将不胜感激。我正在使用Microsoft Visual Studio 2013。
错误: 调试断言失败!
Program: G:\....\Lab6.exe
File: f:\dd\vtools\crt\crtw32\misc\dbgdel.cpp
Line: 52
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.
我的主要(这是由我的教授给出的,我只需要让它有效):
#include "RationalArray.h"
#include "Rational.h"
#include <iostream>
using namespace std;
Rational CalculateMean(RationalArray &numbers);
int main(int argc, char* argv[]) {
RationalArray arr(5);
arr[0].SetNumerator(5);
arr[0].SetDenominator(3);
cout << "arr[0] = " << arr[0] << endl; // what should this print?
arr[1] = Rational(3, -5);
cout << "arr[1] = " << arr[1] << endl << endl;
arr[2] = Rational(8, -2);
arr[3] = Rational(12, 9);
arr[4] = Rational(22, 14);
RationalArray copy(arr);
copy[0].SetNumerator(10);
cout << "copy[0] = " << copy[0] << endl;
cout << "arr[0] = " << arr[0] << endl;
try {
cout << "Accessing arr out of bounds " << endl;
cout << arr[5] << endl;
}
catch (std::out_of_range &ex) {
cout << "Caught the exception" << endl << endl;
}
RationalArray larger(100);
cout << "Remember, all objects in an array are default constructed." << endl;
cout << "So larger[10] should = ... " << larger[10] << endl << endl;
larger = arr;
cout << "Now that arr has been deep-assigned into larger, larger's size is "
<< "... " << larger.Size() << ";" << endl
<< " and its index 0 is " << larger[0] << endl << endl;
larger[0].SetNumerator(15);
cout << "larger[0] = " << larger[0] << endl;
cout << "arr[0] = " << arr[0] << endl << endl;
// TO FINISH THIS ASSIGNMENT, you must implement the CalculateMean function
// below, so that this code correctly outputs the mean value of the five
// numbers in arr.
Rational average = CalculateMean(arr);
cout << "The average of ";
for (int i = 0; i < arr.Size(); i++) {
cout << arr[i];
if (i < arr.Size() - 1)
cout << ", ";
}
cout << " is " << average << endl;
}
Rational CalculateMean(RationalArray &numbers) {
Rational sum;
for (int i = 0; i < numbers.Size(); i++){
sum = sum + numbers[i];
}
Rational size(numbers.Size(), 1);
sum = sum / size;
return sum;
}
RationalArray:
#include <iostream>
#include "Rational.h"
#include "RationalArray.h"
using namespace std;
RationalArray::RationalArray(int size)
: mSize(size)
{
mArray = new Rational [mSize];
}
// Destructor: clean up any memory placed on the heap by this object.
RationalArray::~RationalArray() {
delete[] mArray;
}
// Copy constructor: make a deep copy of the parameter's array.
RationalArray::RationalArray(const RationalArray &other)
: mSize(other.mSize)
{
Rational *rat = other.mArray;
mArray = rat;
}
// Assignment operator: make a deep copy of the rhs parameter. This will
// override any array currently held by this object; do not leak the old
// array!
RationalArray& RationalArray::operator=(const RationalArray& rhs) {
if (this == &rhs)
return *this;
delete mArray;
mSize = rhs.mSize;
if (rhs.mArray != nullptr){
Rational *rat = rhs.mArray;
mArray = rat;
}
else
mArray = nullptr;
return *this;
}
// Indexing operator: given an index, return the value at that index in
// mArray. Should throw std::out_of_range from <stdexcept> if the rhs index
// is not in bounds of the array.
Rational& RationalArray::operator[](int rhs) {
if ( rhs > (mSize-1) )
throw out_of_range("Out of range.");
return *(mArray+rhs);
}
Rational类(我知道它自己工作所以我不认为这是问题):
#include <iostream>
#include <string>
#include <sstream>
#include "Rational.h"
using namespace std;
////////////////////////////////////////////////////////////////////////////////
void Rational::Normalize(){
int gcd = 0;
int num = mNumerator;
int den = mDenominator;
if (num < 0)
num *= -1;
if (den < 0)
den *= -1;
for (int i = 1; i <= num && i <= den; i++){
if (num % i == 0 && den % i == 0)
gcd = i;
}
mNumerator /= gcd;
mDenominator /= gcd;
}
Rational::Rational()
:mNumerator(0), mDenominator(1)
{
}
Rational::Rational(int num, int den)
: mNumerator(num), mDenominator(den)
{
Rational::Normalize();
}
Rational::Rational(const Rational &other)
: mDenominator(other.mDenominator), mNumerator(other.mNumerator)
{
Rational::Normalize();
}
int Rational::GetDenominator() const{
return mDenominator;
}
int Rational::GetNumerator() const{
return mNumerator;
}
void Rational::SetDenominator(int newDen){
mDenominator = newDen;
Normalize();
}
void Rational::SetNumerator(int newNum){
mNumerator = newNum;
Normalize();
}
bool Rational::Equals(const Rational &other) const {
if (other.GetNumerator() == mNumerator &&
other.GetDenominator() == mDenominator)
return true;
return false;
}
Rational Rational::Add(const Rational &other) const {
int newNum = (mNumerator * other.GetDenominator())
+ (other.GetNumerator() * mDenominator);
int newDen = mDenominator * other.GetDenominator();
Rational newRat(newNum, newDen);
return newRat;
}
std::string Rational::ToString() const {
std::ostringstream out;
if (mDenominator == 0) {
out << mNumerator;
return out.str();
}
if (mDenominator < 0) {
out << (mNumerator*-1) << "/" << (mDenominator*-1);
return out.str();
}
else {
out << mNumerator << "/" << mDenominator;
return out.str();
}
}
void Rational::operator=(const Rational &other) {
mNumerator = other.GetNumerator();
mDenominator = other.GetDenominator();
}
Rational operator+(const Rational &lhs, const Rational &rhs) {
Rational r = lhs.Add(rhs);
return r;
}
std::ostream& operator<<(std::ostream &lhs, const Rational &rhs) {
lhs << rhs.ToString();
return lhs;
}
void Rational::operator-() {
mNumerator *= -1;
}
Rational operator-(const Rational &lhs, const Rational &rhs) {
int newNum = (lhs.GetNumerator() * rhs.GetDenominator())
- (rhs.GetNumerator() * lhs.GetDenominator());
int newDen = lhs.GetDenominator() * rhs.GetDenominator();
Rational newRat(newNum, newDen);
return newRat;
}
Rational operator*(const Rational &lhs, const Rational &rhs) {
int newNum = lhs.GetNumerator() * rhs.GetNumerator();
int newDen = lhs.GetDenominator() * rhs.GetDenominator();
Rational newRat(newNum, newDen);
return newRat;
}
Rational operator/(const Rational &lhs, const Rational &rhs) {
int newNum = lhs.GetNumerator() * rhs.GetDenominator();
int newDen = lhs.GetDenominator() * rhs.GetNumerator();
Rational newRat(newNum, newDen);
return newRat;
}
bool operator==(const Rational &lhs, const Rational &rhs) {
return lhs.Equals(rhs);
}
bool operator!=(const Rational &lhs, const Rational &rhs) {
return !lhs.Equals(rhs);
}
bool operator<(const Rational &lhs, const Rational &rhs) {
int num = lhs.GetNumerator() - rhs.GetNumerator();
if (num < 0)
return true;
else
return false;
}
bool operator>(const Rational &lhs, const Rational &rhs) {
int num = lhs.GetNumerator() - rhs.GetNumerator();
if (num > 0)
return true;
else
return false;
}
bool operator<=(const Rational &lhs, const Rational &rhs) {
int num = lhs.GetNumerator() - rhs.GetNumerator();
if (num <= 0)
return true;
else
return false;
}
bool operator>=(const Rational &lhs, const Rational &rhs) {
int num = lhs.GetNumerator() - rhs.GetNumerator();
if (num >= 0)
return true;
else
return false;
}