2015-03-10 4 views
0

Я работаю над этим какое-то время, и все это может превратиться в mush. Я начинаю с C++, и у меня возникает проблема при вызове delete, чтобы удалить элементы в моем массиве. В нем говорится, что утверждение об отладке не удалось. В моей книге и в Интернете я обнаружил, что они делают именно то, что я есть, поэтому я не уверен, почему я получаю эту неудачу. Может ли кто-нибудь помочь? Плюс, я бы не стал против некоторых советов по улучшению.Ошибка отладки C++ при удалении вектора указателя

#include <iostream> 
#include <string> 
#include <vector> 
#include <fstream> 
#include "Account.h" 
#include "Person.h" 
#include "Checkings.h" 
#include "Savings.h" 
#include "AccountException.h" 
using namespace std; 


void printAccountSummary(const vector<Account> &acc); 
string TYPE; 

int main() 
{ 
    cout << "Project 3 - Greg Mora - 601\n" << endl; 
    cout << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n" << endl; 
    cout << "The Avenger's Retirement Fund\n" << endl; 
    cout << "#\tAccount Name \t\tAddress \t\tBalance\n" << endl; 

    vector<Account*> acc; 

    acc.push_back(new Savings(new Person("Bilbo Baggins", "43 Bag End"), 1, 500, 0.075)); 
    acc.push_back(new Checkings(new Person("Wizard Gandalf", "Crystal Palace"), 2, 1000.00, 2.00)); 
    acc.push_back(new Savings(new Person("Elf Elrond", "Rivendell"), 3, 1200, 0.050)); 

    ofstream dataOut("Accounts.txt"); 
    if (dataOut.bad()) 
     cout << "Error: File was unable to open." << endl; 

    for (unsigned int i = 0; i < acc.size(); i++) 
    { 
     acc[i]->writeData(dataOut); 
    } 
    for (unsigned int i = 0; i < acc.size(); i++) 
    { 
     if (acc[i] != nullptr) 
     { 
      delete acc[i]; 
      acc[i] = nullptr; 
     } 
    } 

    dataOut.close(); 
    acc.clear(); 

    try 
    { 
     ifstream dataInput; 
     dataInput.open("Accounts.txt"); 
     if (dataInput.fail()) 
     { 
      cout << "Error: File was unable to open." << endl; 
     } 

     while (!dataInput.eof()) 
     { 
      getline(dataInput, TYPE); 
      if (TYPE=="Savings") 
      { 
       Account* save = new Savings; 
       save->readData(dataInput); 
       acc.push_back(save); 
      } 
      else if (TYPE == "Checkings") 
      { 
       Account* check = new Checkings; 
       check->readData(dataInput); 
       acc.push_back(check); 
      } 
     } 
    } 
    catch (AccountException e) 
    { 
     dataOut.close(); 
     cout << e.getMessage(); 
     system("PAUSE"); 
     return 0; 
    } 

    for (unsigned int i = 0; i < acc.size(); i++) 
    { 
     acc[i]->makeWithdrawl(100.00); 
    } 
    for (unsigned int i = 0; i < acc.size(); i++) 
    { 
     acc[i]->makeDeposit(25.00); 
    } 

    for (unsigned int i = 0; i < acc.size(); i++) 
    { 
     cout << acc[i]->getAccountNumber() << "\t" << acc[i]->getPersonInfo()->getName() << "\t\t" << 
      acc[i]->getPersonInfo()->getAddress() << "\t\t" << acc[i]->getAccountBalance() << endl; 
    } 

    cout << endl << endl; 
    system("PAUSE"); 
    return 0; 
} 

Person.cpp

#include "Person.h" 
using namespace std; 

Person::Person(){ 
    name = ""; 
    address = ""; 
} 

Person::Person(string nameIn, string addressIn) 
{ 
    name = nameIn; 
    address = addressIn; 
} 

string Person::getName() const{ 
    return name; 
} 

string Person::getAddress() const{ 
    return address; 
} 

void Person::writeData(ofstream& output) const 
{ 
    output << name << endl; 
    if (output.bad()) 
    { 
     throw AccountException("Unexpected error occurred during writing out of data"); 
    } 
    output << address << endl; 
    if (output.bad()) 
    { 
     throw AccountException("Unexpected error occurred during writing out of data"); 
    } 
} 

void Person::readData(ifstream& input) 
{ 
    getline(input, name); 
    if (input.bad()) 
    { 
     throw AccountException("Unexpected error occurred during reading in of data"); 
    } 
    getline(input, address); 
    if (input.bad()) 
    { 
     throw AccountException("Unexpected error occurred during reading in of data"); 
    } 
} 

Account.cpp

#include "Account.h" 
#include "Person.h" 
#include "Checkings.h" 
#include "Savings.h" 
#include <iostream> 
#include <string> 
#include <fstream> 
using namespace std; 

Account::Account() 
{ 
    accountNumber = 0; 
    personInfo = nullptr; 
    accountBalance = 0; 
} 

Account::Account(Person *personInfoIn, int accNumIn, double accBalIn) 
{ 
    accountNumber = accNumIn; 
    personInfo = personInfoIn; 
    accountBalance = accBalIn; 
} 

int Account::getAccountNumber() const 
{ 
    return accountNumber; 
} 

double Account::getAccountBalance() const{ 
    return accountBalance; 
} 

Person *Account::getPersonInfo() const{ 
    return personInfo; 
} 

void Account::makeDeposit(double depositAmt){ 
    accountBalance = accountBalance + depositAmt; 
} 

void Account::makeWithdrawl(double withdrawlAmt){ 
    accountBalance = accountBalance - withdrawlAmt; 
} 
Account::~Account(){ 
    if (personInfo != nullptr) 
    { 
     delete[] personInfo; 
     personInfo = nullptr; 
     accountBalance = 0; 
     accountNumber = 0; 
    } 
} 

Savings.cpp

#include "Savings.h" 
#include "Account.h" 
using namespace std; 


Savings::Savings() 
{ 
    accountBalance = 0; 
    intRate = 0;  
} 
Savings::Savings(Person *personInfoIn, int accNumIn, double accBalIn, double intRateIn) 
:Account(personInfoIn, accNumIn, accBalIn) 
{ 
    intRate = intRateIn; 
} 
double Savings::getAccountBalance() const 
{ 
    return accountBalance + (accountBalance * intRate); 
} 
void Savings::readData(ifstream & input) 
{ 
    personInfo = new Person; 
    personInfo->readData(input); 
    input >> accountNumber; 
    if (input.bad()) 
    { 
     throw AccountException("Unexpected error occurred during reading in of data"); 
    } 
    input >> accountBalance; 
    if (input.bad()) 
    { 
     throw AccountException("Unexpected error occurred during reading in of data"); 
    } 
    input.ignore(); 
} 
void Savings::writeData(ofstream & output) const 
{ 
    output << "Savings" << endl; 
    personInfo->writeData(output); 
    output << accountNumber << endl; 
    if (output.bad()) 
    { 
     throw AccountException("Unexpected error occurred during writing out of data"); 
    } 
    output << getAccountBalance() << endl; 
    if (output.bad()) 
    { 
     throw AccountException("Unexpected error occurred during writing out of data"); 
    } 
} 

Checkings.cpp

#include "Checkings.h" 
#include "Account.h" 
using namespace std; 


Checkings::Checkings() 
{ 
    accountBalance = 0; 
    monthlyFee = 0; 
} 
Checkings::Checkings(Person *personInfoIn, int accNumIn, double accBalIn, double monthlyFeeIn) 
: Account(personInfoIn, accNumIn, accBalIn) 
{ 
    monthlyFee = monthlyFeeIn; 
} 
double Checkings::getAccountBalance() const 
{ 
    return accountBalance - monthlyFee; 
} 
void Checkings::readData(ifstream & input) 
{ 
    personInfo = new Person; 
    personInfo->readData(input); 
    input >> accountNumber; 
    if (input.bad()) 
    { 
     throw AccountException("Unexpected error occurred during reading in checking account number"); 
    } 
    input >> accountBalance; 
    if (input.bad()) 
    { 
     throw AccountException("Unexpected error occurred during reading in checking account balance"); 
    } 
    input.ignore(); 
} 
void Checkings::writeData(ofstream & output) const 
{ 
    output << "Checkings" << endl; 
    personInfo->writeData(output); 
    output << accountNumber << endl; 
    if (output.bad()) 
    { 
     throw AccountException("Unexpected error occurred during writing out checking account number"); 
    } 
    output << getAccountBalance() << endl; 
    if (output.bad()) 
    { 
     throw AccountException("Unexpected error occurred during writing out checking account balance"); 
    } 
} 
+0

Вместо того, чтобы делать для петель с индексом "я", использовать итераторы. Если вы используете C++ 11, который похож на вас, вы можете использовать диапазон для цикла. Что касается реальной проблемы, я предполагаю ее на этой линии? "delete acc [i];". В какой строке возникает проблема утверждения? – Mark

+0

Итак, вы предлагаете мне проверить nullptr, прежде чем я запустим три цикла в конце? – ManiacalTeddy

+0

Моя другая проблема в том, что если я прокомментирую цикл, который удаляет элементы и устанавливает значение nullptr, программа запускается. Если я оставлю их, как показано выше, он сбой при вызове удаления. – ManiacalTeddy

ответ

2

Проблема, которую я вижу:

Вы используете operator new создать Person, но вы используете operator delete [], чтобы удалить его. Изменение

Account::~Account(){ 
    if (personInfo != nullptr) 
    { 
     delete[] personInfo; // Problem 
     personInfo = nullptr; 
     accountBalance = 0; 
     accountNumber = 0; 
    } 
} 

в

Account::~Account(){ 
    if (personInfo != nullptr) 
    { 
     delete personInfo; 
     personInfo = nullptr; 
     accountBalance = 0; 
     accountNumber = 0; 
    } 
} 
+0

Ты лучший! Это решило мою проблему.Я не собираюсь лгать, я чувствую себя глупо для этого, так как я скопировал и вставил. Я знаю, что не делаю этого, и я этого не сделал, но почему я сделал это на этот раз; кто знает? – ManiacalTeddy

0

У вас есть петля в начале программы, где вы удаляете элементы в векторе acc и устанавливаете указатели на nullptr, однако это не удаляет элементы из вектора. Затем в конце программы у вас есть три петли, которые зацикливаются на все элементов в векторе (включая те, которые вы уничтожили) и разыгрываете указатели без проверки на nullptr.

Вывод оговорки nullptr приводит к undefined behavior и, скорее всего, к вашему сбою.

Есть два возможных решения, которые приходят на ум: либо очистить вектор после цикла уничтожения, либо добавить проверки для nullptr в другие циклы.

+0

. Моя проблема в том, что я даже не могу получить переданное удаление, поэтому на самом деле никогда не вызывает следующую строку, которая устанавливает значение nullptr. Если я прокомментирую этот блок кода, он работает отлично. (Я знаю, что вызывает утечку памяти, но это было просто наблюдение). – ManiacalTeddy

+0

Существует строка для очистки вектора - 'acc.clear();'. –

Смежные вопросы