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