抛出std :: bad_alloc的实例后调用Terminate。使用两个类,其中一个指向另一个指针
当我使用包含成员函数的普通函数时,我的程序不断收到错误的alloc错误。抛出std :: bad_alloc的实例后调用Terminate。使用两个类,其中一个指向另一个指针
该程序是关于从命令行获取一些特定的输入并打印指针数组的元素。这必须通过指针数组完成。
首先,我创建了一个需要2个字符串的类。一个用于名称,另一个用于房间。然后,我创建了另一个具有大小和指向我的第一个类的指针,以创建一个数组。
我的主要是在最后,以上主要是2正常功能。这段代码有什么问题?当我第一次输入命令时,它会运行,直到我输入一个连接到普通函数的命令。那里可能有些问题,但我似乎无法找到它。
#include <iostream>
#include <string>
using namespace std;
class Address
{
private:
string name;
string room;
public:
Address(){};
Address(string, string);
string get_name();
string get_room();
void change_room(string);
};
Address::Address (string n, string r)
{
name = n;
room = r;
}
string Address::get_name()
{
return name;
}
string Address::get_room()
{
return room;
}
void Address::change_room(string change)
{
room = change;
}
//end of Address class
class Address_Book
{
private:
int size;
Address* addresses;
public:
Address_Book();
~Address_Book(){ delete[] addresses;}
void add(Address);
void move(string, string);
int get_size();
Address location(int);
int find(string);
void clear();
void remove_address(string);
int exists(string);
void sort();
};
Address_Book::Address_Book()
{
int s = 0;
size = s;
addresses = new Address[s];
}
void Address_Book::add(Address add)
{
Address* temp = new Address [size + 1];
for (int i = 0; i < size; i++)
{
temp[i] = addresses[i];
}
temp[size] = add;
delete[] addresses;
addresses = temp;
size ++;
}
void Address_Book::move(string name, string newroom)
{
for (int i = 0; i < size ; i++)
{
if (addresses[i].get_name() == name)
{
addresses[i].change_room(newroom);
}
}
}
void Address_Book::remove_address(string name)
{
Address* temp = new Address [size - 1];
for (int i = 0; i < size; i++)
{
if (addresses[i].get_name() != name)
{
temp[i] = addresses[i];
}
else if (addresses[i].get_name() == name)
{
for (int j = i + 1; j < size; j++)
{
temp[i] = addresses[j];
i++;
}
break;
}
}
delete[] addresses;
addresses = temp;
size--;
}
int Address_Book::get_size()
{
return size;
}
Address Address_Book::location(int index)
{
return addresses[index];
}
void Address_Book::sort()
{
Address temp;
for (int i = 0; i < size; i++)
{
for(int j = 0; j < size - 1; j++)
{
if (addresses[j].get_room() > addresses[j + 1].get_room())
{
temp = addresses[j];
addresses[j] = addresses[j + 1];
addresses[j + 1] = temp;
}
}
}
for (int i = 0; i < size; i++)
{
if (addresses[i].get_room() == addresses[i + 1].get_room())
{
if (addresses[i].get_name() > addresses[i + 1].get_name())
{
temp = addresses[i];
addresses[i] = addresses[i + 1];
addresses[i + 1] = temp;
}
}
}
}
void Address_Book::clear()
{
Address * temp = new Address[0];
delete[] addresses;
addresses = temp;
size = 0;
}
int Address_Book::find(string name)
{
for (int i = 0; i < size; i++)
{
if (addresses[i].get_name() == name)
{
return i;
}
}
return -1;
}
//end of Address_Book class
void find(string name, Address_Book addbook)
{
int index = addbook.find(name);
cout << index << endl;
if (index > -1)
{
cout << addbook.location(index).get_name() << " is in room " <<
addbook.location(index).get_room() << endl;
}
else
{
throw runtime_error("entry does not exist.");
}
}
void remove_add(string name, Address_Book book)
{
int exist = book.find(name);
if (exist > -1)
{
book.remove_address(name);
}
else
{
throw runtime_error("entry does not existt.");
}
}
int main()
{
Address_Book addbook;
string action, in_name, in_room;
do
{
try
{
cout << "> ";
cin >> action;
if (action == "add")
{
cin >> in_name >> in_room;
Address newadd(in_name, in_room);
addbook.add(newadd);
}
else if (action == "move")
{
cin >> in_name >> in_room;
addbook.move(in_name, in_room);
}
else if (action == "remove")
{
cin >> in_name;
remove_add(in_name, addbook);
}
else if (action == "find")
{
cin >> in_name;
find(in_name, addbook);
}
else if (action == "list")
{
addbook.sort();
for (int i = 0; i < addbook.get_size(); i++)
{
cout << addbook.location(i).get_name() << " is in room
" << addbook.location(i).get_room() << endl;
}
}
else if (action == "clear")
{
addbook.clear();
}
else
{
throw runtime_error("input mismatch.");
}
}
catch (runtime_error& e)
{
cerr << "error: " << e.what() << endl;
}
}while (action != "exit");
return 0;
}
函数remove_add
需要通过引用或指针获取地址簿对象。 它现在的样子,从地址簿的副本中删除。
它应该是这样的:
void remove_add(string name, Address_Book& book)
{
int exist = book.find(name);
if (exist > -1)
{
book.remove_address(name);
}
else
{
throw runtime_error("entry does not existt.");
}
}
此外,你应该做的事情,在下面的功能的情况下size == 1
不同。例如如果您的编译器支持它,请将addresses
设置为NULL
,0或nullptr
。
void Address_Book::remove_address(string name)
{
Address* temp = new Address[size - 1];
for (int i = 0; i < size; i++)
{
if (addresses[i].get_name() != name)
{
temp[i] = addresses[i];
}
else if (addresses[i].get_name() == name)
{
for (int j = i + 1; j < size; j++)
{
temp[i] = addresses[j];
i++;
}
break;
}
}
delete[] addresses;
addresses = temp;
size--;
}
玩得开心学习语言和好运:)
哦。现在我明白了......我非常感谢你,你能否请进一步解释为什么会发生这种情况? –
尝试阅读关于按值传递与传递参考的比较,将会有大量的解释比我提供的要好。 – CplusPuzzle
导致你的问题的确切命令你的问题没有规定,所以我周围戳一点点,直到代码段故障而坠毁。
Valgrind和Dr. Memory是找到这些问题的根本原因很棒的工具。你的情况:
$ g++ -g 46865300.cpp
$ valgrind ./a.out
> add foo bar
> list
==102== Invalid read of size 8
==102== at 0x4EF4EF8: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&) (in /usr/lib64/libstdc++.so.6.0.19)
==102== by 0x401354: Address::get_room() (46865300.cpp:33)
==102== by 0x401C05: Address_Book::sort() (46865300.cpp:152)
==102== by 0x4026A3: main (46865300.cpp:262)
==102== Address 0x5a17410 is 8 bytes after a block of size 24 alloc'd
==102== at 0x4C2A8A8: operator new[](unsigned long) (vg_replace_malloc.c:423)
==102== by 0x4014BF: Address_Book::add(Address) (46865300.cpp:74)
==102== by 0x40245C: main (46865300.cpp:243)
它说,下面的代码进行了界外接入:
150 for (int i = 0; i < size; i++)
151 {
152 if (addresses[i].get_room() == addresses[i + 1].get_room())
153 {
154 if (addresses[i].get_name() > addresses[i + 1].get_name())
我猜循环条件应该用“大小 - 1”而不是“大小”。
这不是问题。尝试输入:'添加'John F450,然后添加其他人,例如'添加'弗兰克T430。然后输入'list'。然后输入'find'John(它应该打印正确的输出),但是当我再次输入'list'或尝试再次'查找'时,它会给出错误的分配或双倍空闲或损坏 –
将有助于了解你使用的是什么操作系统,编译器等。 导致问题的输入示例会很有帮助。 此外,请让我们知道什么是在屏幕上打印。 – CplusPuzzle
我必须重新创建这个向量。它是必须使用的。我需要了解记忆是如何工作的。 –
操作系统是mac。当我输入'add'后跟着名字和一个房间时,他们直接进入我创建的地址数组。当我输入'list'时,它会打印整个数组。但是,当我想删除或找到它只有第一次。那么它会给我一个糟糕的分配()。这是怎么回事? –