2012-03-12 2 views
4

죄송합니다, 이것이 Stack Overflow에 관한 umpteenth seg 오류 게시물이라는 것을 알고 있습니다 만,이 코드를 수정하기 위해 며칠 동안 노력했지만 난 곤경에 처했습니다. 얘들 아. 네가 도울 수 있기를 바란다. 나는 할당에 따라, 어쨌든에 account.h 파일을 수정 허용되지 않아Strange Seg 오류

account.h (참고 :

:

어쨌든,이 코드에서 이상한 세그먼트 폴트를 얻고있다.

class account 
    { 
    public: 
    typedef char* string; 
    static const size_t MAX_NAME_SIZE = 15; 
     // CONSTRUCTOR 
    //account(); 
    account (char* i_name, size_t i_acnum, size_t i_hsize); 
    account (const account& ac); 
    // DESTRUCTOR 
    ~account (); 
     // MODIFICATION MEMBER FUNCTIONS 
    void set_name(char* new_name); 
    void set_account_number(size_t new_acnum); 
    void set_balance(double new_balance); 
    void add_history(char* new_history); 
    // CONSTANT MEMBER FUNCTIONS 
    char* get_name() const; 
    size_t get_account_number () const; 
    double get_balance() const; 
    size_t get_max_history_size() const; 
    size_t get_current_history_size () const; 
    string* get_history() const; 
    friend std::ostream& operator <<(std::ostream& outs, const account& target); 
    private: 
    char name[MAX_NAME_SIZE+1]; //name of the account holder 
    size_t ac_number; //account number 
    double balance; //current account balance 
    string* history; //Array to store history of transactions 
    size_t history_size; //Maximum size of transaction history 
    size_t history_count; //Current size of transaction history 
    }; 

account.cxx :

#include <string.h> 
#include <cassert> 
#include <cstdlib> 
#include <iostream> 
#include "account.h" 

using namespace std; 

account::account(char* i_name, size_t i_acnum, size_t i_hsize) 
{ 
    assert(strlen(i_name) <= MAX_NAME_SIZE); 
    strcpy(name, i_name); 
    ac_number = i_acnum; 
    history_size = i_hsize; 
    balance = 0; 
    history_count = 0; 
    history = new string[history_size]; 
} 

account::account(const account& ac) 
{ 
    strcpy(name, ac.name); 
    ac_number = ac.ac_number; 
    balance = ac.balance; 

    history = new string[ac.history_size]; 
    for(size_t i = 0; i < ac.history_count; i++) 
    { 
     history[i] = new char[strlen(ac.history[i]) + 1]; 
     strcpy(history[i], ac.history[i]); 
    } 


    history_count = ac.history_count; 
    history_size = ac.history_size; 
} 

account::~account() 
{ 
    delete[] history; 
} 

void account::set_name(char* new_name) 
{ 
    assert(strlen(new_name) <= MAX_NAME_SIZE); 
    strcpy(name, new_name); 
} 

void account::set_account_number(size_t new_acnum) {ac_number = new_acnum;} 
void account::set_balance(double new_balance) {balance = new_balance;} 

void account::add_history(char* new_history) 
{ 
    assert(history_count < history_size); 
    history[history_count] = new char[strlen(new_history) + 1]; 
    strcpy(history[history_count], new_history); 
    history_count++; 
} 

char* account::get_name() const 
{ 
    char* blah = new char[MAX_NAME_SIZE + 1]; 
    strcpy(blah, name); 
    return blah; 
} 

size_t account::get_account_number () const {return ac_number;} 
double account::get_balance() const{return balance;} 
size_t account::get_max_history_size() const {return history_size;} 
size_t account::get_current_history_size () const {return history_count;} 

account::string* account::get_history() const 
{ 
    string* blah = new string[history_size]; 

    for(size_t i = 0; i < history_count; i++) 
    { 
     blah[i] = new char[strlen(history[i]) + 1]; 
     strcpy(blah[i], history[i]); 
    } 
    return blah; 
} 

std::ostream& operator<< (std::ostream& outs, const account& target) 
{ 
    outs << "Name: " << target.name << "\n" 
    << "Account Number: " << target.ac_number << "\n" 
    << "Balance: " << "$" << target.balance << "\n" 
    << "History: "; 

    for(size_t i = 0; i < target.history_count; i++) 
    { 
     outs << target.history[i] << "\n"; 
    } 

    outs << "Current History Size: " << target.history_count << "\n"; 
    outs << "Max History Size: " << target.history_size << "\n"; 
    return outs; 
} 

bankledger.h

class bank_ledger 
{ 
public: 
    static const int MAX_ACC_SIZE = 15; 
    bank_ledger(int mo, int mc); 
    bank_ledger(const bank_ledger& copyledger); 
    ~bank_ledger(); 
    void create_account(char* i_name, size_t i_acnum, size_t i_hsize); 
    void close_account(double accnum); 
    double balance_of(double accnum); 
    void deposit(double accnum, double money); 
    void withdraw(double accnum, double money); 
    void transfer(double accnum1, double accnum2, double money); 
    void print_account_history(double accnum); 
    void print_account_details(double accnum); 
    void print_current_details(); 
    void print_closed_details(); 
    account* lookup(double accnum); 
private: 
    account** open; 
    account** closed; 
    int max_open; 
    int max_closed; 
    int num_open; 
    int num_closed; 
}; 
,691 363,210

bankledger.cxx :

#include <cstdlib> 
#include <iostream> 
#include <cassert> 
#include "account.h" 
#include "bank_ledger.h" 

using namespace std; 

bank_ledger::bank_ledger(int mo = 30, int mc = 30) 
{ 
    max_open = mo; 
    max_closed = mc; 
    open = new account*[max_open]; 
    closed = new account*[max_closed]; 
    num_open = 0; 
    num_closed = 0; 
} 

bank_ledger::bank_ledger(const bank_ledger& copyledger) 
{ 
    int i; 
    max_open = copyledger.max_open; 
    max_closed = copyledger.max_closed; 
    num_open = copyledger.num_open; 
    num_closed = copyledger.num_closed; 

    open = new account*[num_open]; 
    closed = new account*[num_closed]; 


    for(i = 0; i < max_open; i++) 
    { 
     if (i < num_open) 
     open[i] = copyledger.open[i]; 
    } 

    for(i = 0; i < max_closed; i++) 
    { 
     if (i < num_closed) 
     closed[i] = copyledger.closed[i]; 
    } 
} 

bank_ledger::~bank_ledger() 
{ 
    for(int i = 0; i < num_open; i++) 
    { 
     delete open[i]; 
    } 
    for(int i = 0; i < num_closed; i++) 
    { 
     delete closed[i]; 
    } 
    delete[] open; 
    delete[] closed; 
} 

account* bank_ledger::lookup(double accnum) 
{ 
    for(int i = 0; i < num_open; i++) 
    {  
     if(open[i]->get_account_number() == accnum) 
     { 
      return *open + i; 
     } 

     if(closed[i]->get_account_number() == accnum) 
     { 
      return *closed + i; 
     } 
    } 
} 

void bank_ledger::create_account(char* i_name, size_t i_acnum, size_t i_hsize) 
{ 
    assert(num_open < max_open); 
    open[num_open] = new account(i_name, i_acnum, i_hsize); 
    open[num_open]->add_history("Account Created"); 
    num_open++; 
} 
void bank_ledger::close_account(double accnum) 
{ 
    int i; 
    double temp = -1; 
    cout << *(open[0]) << endl << "Good Idea" << endl; 

    account* acc = lookup(accnum); 

    for(i = 0; i < num_open; i++) 
    { 
     if(open[i]->get_account_number() == acc->get_account_number()) 
     { 
      temp = i; 
      closed[num_closed] = open[i]; 
      for(i = temp; i < num_open - 1; i++) 
      { 
       open[i] = open[i+1]; 
      } 
      closed[num_closed]->add_history("Account Closed"); 
      num_open--; 
      num_closed++; 
      return; 
     } 
    } 
} 
double bank_ledger::balance_of(double accnum) 
{ 
    return lookup(accnum)->get_balance(); 
} 
void bank_ledger::deposit(double accnum, double money) 
{ 
    account* acc = lookup(accnum); 
    acc->set_balance(acc->get_balance() + money); 
    acc->add_history("Deposited $"); 
} 
void bank_ledger::withdraw(double accnum, double money) 
{ 
    account* acc = lookup(accnum); 
    acc->set_balance(acc->get_balance() - money); 
    acc->add_history("Withdrew $"); 
} 
void bank_ledger::transfer(double accnum1, double accnum2, double money) 
{ 
    withdraw(accnum2, money); 
    deposit(accnum1, money); 
} 
void bank_ledger::print_account_history(double accnum) 
{ 
    account* acc = lookup(accnum); 
    account::string *hist = acc->get_history(); 
    cout << "History of " << acc->get_name() << "'s account: " << endl; 
    for (int i = 0; i < acc->get_current_history_size(); i++) cout << hist[i] << endl; 
} 
void bank_ledger::print_account_details(double accnum) 
{ 
    account* acc = lookup(accnum); 
    cout << *acc; 
    cout << "\n"; 
} 
void bank_ledger::print_current_details() 
{ 
    for(int i = 0; i < num_open; i++) 
    { 
     cout << *open[i] << "\n"; 
    } 
} 
void bank_ledger::print_closed_details() 
{ 
    for(int i = 0; i < num_closed; i++) 
    { 
     cout << *closed[i] << "\n"; 
    } 
    cout << "\n"; 
} 

sample_test_input2.cxx는

#include <cstdlib> 
#include <iostream> 
#include "account.h" 
#include "bank_ledger.h" 

using namespace std; 

int main() 
{ 
    bank_ledger bl(30, 30); 
    bl.create_account("name1", 1, 30); 
    bl.create_account("name2", 2, 30); 
    bl.create_account("name3", 3, 30); 
    bl.create_account("name4", 4, 30); 

    bl.print_current_details(); 
    bl.close_account(2); 
    return 0; 
} 

는 Valgrind의 GDB와 모두는 *가 (오픈 [I]) 초기화 말한다. 그것을 잘 그것을 밖으로 인쇄,

==7082== Use of uninitialised value of size 8 
==7082== at 0x1000018C6: account::get_account_number() const (account.cxx:74) 
==7082== by 0x10000246B: bank_ledger::lookup(double) (bank_ledger.cxx:85) 
==7082== by 0x1000027D0: bank_ledger::close_account(double) (bank_ledger.cxx:105) 
==7082== by 0x100003117: main (sample_test_input2.cxx:17) 
==7082== 
==7082== Invalid read of size 8 
==7082== at 0x1000018C6: account::get_account_number() const (account.cxx:74) 
==7082== by 0x10000246B: bank_ledger::lookup(double) (bank_ledger.cxx:85) 
==7082== by 0x1000027D0: bank_ledger::close_account(double) (bank_ledger.cxx:105) 
==7082== by 0x100003117: main (sample_test_input2.cxx:17) 
==7082== Address 0x10 is not stack'd, malloc'd or (recently) free'd 

bankledger::lookup에, bankledgrer::close_account로 주에서 이동하고 내가 바로 그 라인 전에 cout << *(open[i]) 스틱 경우는 if(open[i]->get_account_number() == accnum)

에 충돌 : 여기에 Valgrind의에서 정확한 출력입니다. 나는 잃어버린 것 같습니다. 어떤 도움을 주시면 감사하겠습니다. 헤더 파일을 포함 시키거나 아무것도 명확하게하려면 알려주십시오.

추신. 또한,이 코드는 매우 C라는 것을 알고 있지만, C++ 클래스 임에도 불구하고 그것이 내 교수가 원하는 방식입니다. 그림을 이동. : \이 방법에서는

+1

+1 for valgrind! – pyCthon

+0

오류가 결정적입니까? – pg1989

+1

'account.h'와'bank_ledger.h '에는 무엇이 있습니까? 생성자가 모든 것을 올바르게 초기화 했습니까? 왜 계좌 번호에'double'과 때때로'size_t'를 사용합니까? –

답변

4

:

account* bank_ledger::lookup(double accnum) 
{ 
    for(int i = 0; i < num_open; i++) 
    {  
     if(open[i]->get_account_number() == accnum) 
     { 
      return *open + i; 
     } 

     if(closed[i]->get_account_number() == accnum) 
     { 
      return *closed + i; 
     } 
    } 
} 

당신은 열려있는 계정의 금액보다 폐쇄 된 계정의 적어도 같은 양의가 가정합니다. closed [i], i = 1,2,3 ...에 액세스하려고하기 때문에 다른 루프에서 열기 및 닫기 배열을 반복해야하며 closed에는 유효한 포인터가 포함되어 있지 않습니다. NULL 포인터). 이것은 (내가 다른 것을 놓치지 않는 한) 작동합니다 :

account* bank_ledger::lookup(double accnum) { 
    for(int i = 0; i < num_open; i++) {  
     if(open[i]->get_account_number() == accnum) 
      return open[i]; 
    } 
    for(int i = 0; i < num_closed; i++) {  
     if(closed[i]->get_account_number() == accnum) 
      return closed[i]; 
    } 
    return 0; 
} 
+0

고마워요! 그랬어! 내 원래 코드가 open [i] -> get_account_number() == accnum에서 충돌했지만이 문제가 해결 된 것 같습니다. 문제가되는 닫힌 색인이라면 왜 그것이 열린 [i] -> segfault를 일으키는 지 알 수 있습니까? – vanchagreen

+0

잘 모르겠 음 : /. 나는 그것을 알아 내기 위해 노력하고 있지만 이해가되지 않는다. 그것은 closed [i] null pointer-dereference에서 충돌해야합니다. 이상한 ... – mfontanini

+0

어쩌면 그것은, 그리고 컴파일러/valgrind 그냥 점점 잘못입니까? – vanchagreen