C++ 分段错误:C+中的11和malloc错误+;代码

C++ 分段错误:C+中的11和malloc错误+;代码,c++,segmentation-fault,malloc,C++,Segmentation Fault,Malloc,好的,我知道这段代码中可能有很多错误。我对动态内存分配、指针等相当陌生 头文件account.h是我们的教授给我们的。我们被告知不要对.h文件进行任何更改 实现文件是我写的。主要功能仅用于基本的初始测试。我们得到了另一个文件来实际测试account类的实现 如果我不注释掉cout name行,我会得到seg fault 11错误。 如果我这样做,它将打印帐号,但抛出以下错误: 测试(29976)malloc:*对象0x62c1aa18c9d8374的错误:未分配要释放的指针*在malloc\u

好的,我知道这段代码中可能有很多错误。我对动态内存分配、指针等相当陌生

头文件account.h是我们的教授给我们的。我们被告知不要对.h文件进行任何更改

实现文件是我写的。主要功能仅用于基本的初始测试。我们得到了另一个文件来实际测试account类的实现

如果我不注释掉cout name行,我会得到seg fault 11错误。 如果我这样做,它将打印帐号,但抛出以下错误:

测试(29976)malloc:*对象0x62c1aa18c9d8374的错误:未分配要释放的指针*在malloc\u error\u 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
};
类帐户
{
公众:
typedef char*字符串;
静态常量大小\u t最大名称\u大小=15;
//建造师
帐户(字符*名称、大小、数量、大小);
账户(const账户和ac);
//析构函数
~account();
//修改成员函数
无效集合名称(字符*新名称);
作废设置账号(大小为新账号);
无效设置余额(双倍新余额);
作废添加历史记录(字符*新历史记录);
//常数成员函数
char*get_name()常量;
大小获取帐号()常量;
双倍获得平衡()常数;
大小\u无法获取\u最大\u历史\u大小()常量;
大小\u无法获取\u当前\u历史\u大小()常量;
字符串*get_history()常量;

friend ostream&operator在
帐户的析构函数中,删除
历史
数组。但是,在构造函数中,分配(和泄漏)存储在局部变量
d_history
中的数组。您可能想将其分配给成员变量
history
——因为您没有,如果您到达析构函数,它会给您一个错误,说明您正在释放
history
,但从未分配它

复制构造函数中也存在类似的错误


您的代码中也存在其他错误,我想您会发现这些错误-
get_name()
,例如,这些错误不起作用。我怀疑头文件在这里没有帮助,但如果您不想更改这些错误,那么就没有什么可以做的了。

我已经为您编写了一些代码,并更正了这些错误(即使是在头文件中,对不起;)。它仍然非常难看和c-ish,但也许你可以从中学习一些东西:

#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';
}
#包括
#包括
类别帐户
{
//整堂课毫无意义,因为它没有任何用处
//成员函数或类似的东西。
//此外,该类提供对其所有成员变量的几乎完全访问。
//在这一点上,我们可以把一切公之于众。
//当构造函数抛出时,这甚至不是异常安全的。
//一个好的实现将使用历史输入和历史类,
//与std::string和std::vector/std::deque一起使用
//它将提供某种功能
公众:
帐户(常量字符*名称、无符号数字、标准::大小\u t历史\u最大大小);
账户(施工账户和其他账户);
~account();
常量字符*name()常量;
无符号数()常量;
双平衡常数;
常量字符*常量*历史()常量;
std::size\u t history\u size()常量;
未签名的历史\u max\u size()常量;
无效集合名称(常量字符*新名称);
无效集合编号(未签名的新编号);
无效设置余额(双倍新余额);
void add_history(const char*new_history);
私人:
字符*名称u;
无符号数;
双平衡;
字符**历史?;
标准::大小\u t历史\u大小\u;
常量标准::大小\u t历史\u最大\u大小\u;
};

STD:OrStand:如果你正在编写C++,你应该更喜欢<代码>新< /C> > />代码>删除< /C> > <代码> Mulalc < /Calp> /Cudio> < /Cord>。而且,除非你真正知道你在做什么,否则你应该使用智能指针来管理事情。这个错误告诉你如何调试这个:“在MalLogyError Surf中设置断点进行调试。”你做了吗?你发现了什么?如果你的老师给你那个头文件,请告诉他应该拿起,不要教学生写质量差的C++代码。不可能正确地实现那个类:它拥有资源,但不提供用户声明的拷贝赋值操作符。头文件是如此糟糕。,这一点都不好笑。此外,你似乎不明白这一点,我不知道该从何开始。看看你的get_name实现。你认为这是在做什么?首先你向一个未初始化的指针写入,然后返回它的值。但你为什么要复制它?哦,我明白了,你的教授似乎不知道st正确性。结论:请分别学习各个部分,并提出更小的问题。--使用此头文件,不可能编写干净的代码。只需查看get_name()declaration.no我没有在malloc\u error\u break中设置断点…我正在使用mac terminal的g++进行编译,不知道如何在malloc\u error\u break中设置符号断点…有人知道我会怎么做吗?
#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';
}