2012-03-03 3 views
0

그래,이 코드에는 많은 오류가 있음을 알고 있습니다. 나는 동적 메모리 할당, 포인터 등세그먼트 오류 : C++ 코드의 11 및 malloc 오류

헤더 파일, account.h 꽤 새로운 해요, 우리 교수가 우리에게 주어집니다. 우리는 .h 파일을 변경하지 말 것을 들었다.

구현 파일은 저에 의해 작성되었습니다. 주요 기능은 기본 초기 테스트에만 포함됩니다. 실제로 계정 클래스의 구현을 테스트하기 위해 다른 파일이 제공되었습니다. 나는 cout을 이름 라인을 언급하지 않는 경우

, 나는 독방 감금 오류 11 오류가 발생합니다. 내가 할 경우 , 그것은 계좌 번호를 인쇄하지만,이 오류를 던질거야 :

시험 (29976)의 malloc을 : *에 대한 오류 객체 0x62c1aa18c9d8374 : 포인터 디버그에 malloc_error_break에 중단 점을 설정 * 할당되지 않은 해제되고
트랩 중단 : 6

아무런 도움이 필요 없으므로 도움을 받으십시오. 여기

class account 
{ 
public: 
    typedef char* string; 
    static const size_t MAX_NAME_SIZE = 15; 
    // CONSTRUCTOR 
    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 ostream& operator <<(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 
}; 

을 구현 파일입니다 :

여기 헤더 파일의

// File: account.cxx 
// Author: Mike Travis 
// Last Modified: Mar 3, 2012 
// Description: implementation of Account class as prescribed by the file account.h 

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

using namespace std; 

//Constructor 

account::account(char* i_name, size_t i_acnum, size_t i_hsize){ 
    string *d_history; 
    d_history = new string[i_hsize]; 

    for(int i = 0; i<i_hsize; i++){ 
     name[i] = i_name[i]; 
    } 
    ac_number = i_acnum; 
    history_size = i_hsize; 
    history_count = 0; 
} 


account::account(const account& ac){ 
    string *d_history; 
    d_history = new string[ac.history_size]; 

    for(int i=0; i<ac.get_current_history_size(); i++){ 
     strcpy(d_history[i], history[i]); 
    } 

    strcpy(name,ac.get_name()); 
    ac_number = ac.get_account_number(); 
    history_size = ac.get_max_history_size(); 
    history_count = ac.get_current_history_size(); 
} 

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

void account::set_name(char* new_name){     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){ 
    strcpy(history[history_count], new_history); 
    history_count++; 
} 

char* account::get_name() const { 
    char* name_cpy; 
    strcpy(name_cpy, name); 
    return name_cpy; 
} 

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; } 
//string* account::get_history() const{       return *history;  } 


int main(){ 

    account test1("mike travis", 12345, 20); 
    //cout<<"\nname: "<< test1.get_name(); 

    cout<<"\n\nacnum: "<<test1.get_account_number()<<"\n\n"; 

    return 0; 
} 
+1

당신이 C++를 작성하는 경우, 당신은'malloc' /'free'에'new' /'delete'를 선호한다. 그리고 당신이하는 일을 정말로 알지 못한다면, 스마트 포인터를 사용하여 물건을 관리해야합니다. –

+0

이 오류를 디버그하는 방법을 알려줍니다 : "디버깅을 위해 malloc_error_break에 중단 점 설정". 이거 해 봤니? 무엇을 발견 했습니까? –

+4

강사가 해당 헤더 파일을 제공 한 경우 [좋은 C++ 책] (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)을 가져와야한다고 알려주십시오.) 학생들에게 열등한 C++ 코드를 작성하도록 가르치지 마십시오. 이 클래스를 올바르게 구현하는 것은 불가능합니다. 리소스를 소유하지만 사용자가 선언 한 복사본 할당 연산자를 제공하지 않습니다. –

답변

1

account의 소멸자에서, 당신은 history 배열을 삭제합니다. 그러나 생성자에서는 로컬 변수 d_history에 저장된 배열을 할당 (누출)합니다. 당신은 아마도 멤버 변수 history에 할당하려고했을 것입니다. 그렇지 않다면, 소멸자에 도달하면 history을 풀어 본 적이 없다는 오류가 발생합니다.

복사 생성자에서도 비슷한 오류가 발생합니다. get_name(), 예를 들어, 작동하지 않을 -

또한 당신이 가서 당신이 찾을 수 있습니다 가정 다른 코드에서 오류뿐만 아니라,있다. 나는 헤더 파일이 여기에서 도움이되지 않는다고 생각하지만, 당신이 그것을 바꾸기로되어 있지 않다면 할 일이별로 없다.

0

내가 서사시 실수를 당신을 위해 약간의 코드를 작성하고 수정 한 (심지어 헤더 파일, 죄송합니다;)). 그것은 여전히 ​​매우 추한와 C 틱이지만, 어쩌면 당신은 그것을 읽고 뭔가를 배울 수 있습니다

#include <cstddef> 
#include <ostream> 

class account 
{ 
    // The whole class makes no sense, since it has no useful 
    // member function or anything like this. 
    // Furthermore, the class provides almost full access to all its member variables. 
    // At this point one could just make everything public. 

    // This is not even exception safe when the constructor throws. 
    // A good implementation would use history_entry and history classes, 
    // together with std::string and std::vector/std::deque 
    // And it would provide some sort of functionality. ;) 

public: 
    account(const char* name, unsigned number, std::size_t history_max_size); 
    account(const account& other); 
    ~account(); 

    const char* name() const; 
    unsigned number() const; 
    double balance() const; 
    const char* const* history() const; 
    std::size_t history_size() const; 
    unsigned history_max_size() const; 

    void set_name(const char* new_name); 
    void set_number(unsigned new_number); 
    void set_balance(double new_balance); 
    void add_history(const char* new_history); 

private: 
    char* name_; 
    unsigned number_; 
    double balance_; 
    char** history_; 
    std::size_t history_size_; 
    const std::size_t history_max_size_; 
}; 

std::ostream& operator << (std::ostream& stream, const account& a); 


#include <cassert> 
#include <cstring> 

account::account(const char* name, unsigned number, std::size_t history_max_size) 
    : name_(0) 
    , number_(number) 
    , balance_(0.0) 
    , history_(new char*[history_max_size]) 
    , history_size_(0) 
    , history_max_size_(history_max_size) 
{ 
    assert(name != 0); 
    assert(history_max_size != 0); 
    set_name(name); 
} 

account::account(const account& other) 
    : name_(0) 
    , number_(other.number_) 
    , balance_(other.balance_) 
    , history_(new char*[other.history_max_size_]) 
    , history_size_(other.history_size_) 
    , history_max_size_(other.history_max_size_) 
{ 
    set_name(other.name_); 
    for (std::size_t i = 0; i != other.history_size_; ++i) 
    { 
     history_[i] = new char[std::strlen(other.history_[i]) + 1]; 
     strcpy(history_[i], other.history_[i]); 
    } 
} 

account::~account() 
{ 
    delete[] name_; 

    for (std::size_t i = 0; i != history_size_; ++i) 
     delete[] history_[i]; 
    delete[] history_; 
} 

const char* account::name() const 
{ 
    return name_; 
} 

unsigned account::number() const 
{ 
    return number_; 
} 

double account::balance() const 
{ 
    return balance_; 
} 

const char* const* account::history() const 
{ 
    return history_; 
} 

std::size_t account::history_size() const 
{ 
    return history_size_; 
} 

unsigned account::history_max_size() const 
{ 
    return history_max_size_; 
} 

void account::set_name(const char* new_name) 
{ 
    if (name_) 
     delete[] name_; 

    name_ = new char[std::strlen(new_name) + 1]; 
    std::strcpy(name_, new_name); 
} 

void account::set_number(unsigned new_number) 
{ 
    number_ = new_number; 
} 

void account::set_balance(double new_balance) 
{ 
    balance_ = new_balance; 
} 

void account::add_history(const char* new_history) 
{ 
    if (history_size_ == history_max_size_) 
    { 
     delete[] history_[0]; // delete oldest entry 
     for (std::size_t i = 0; i != history_size_ - 1; ++i) 
      history_[i] = history_[i + 1]; 
     --history_size_; 
    } 

    history_[history_size_] = new char[strlen(new_history) + 1]; 
    std::strcpy(history_[history_size_], new_history); 
    ++history_size_; 
} 

std::ostream& operator << (std::ostream& stream, const account& a) 
{ 
    return stream << "account [name: " << a.name() << ", number: " 
     << a.number() << ", balance: " << a.balance() << ']'; 
} 


#include <iostream> 

int main() 
{ 
    account a("Hello!", 500, 5); 
    a.set_balance(12.546); 
    for (int i = 50; i--;) 
     a.add_history("Yaaay.."); 
    //account b = a; 
    std::cout << a << '\n'; 
}