【发布时间】:2014-07-29 14:30:12
【问题描述】:
对于 Accelerated C++ 的练习,我正在实现一个名为 Str 的自定义字符串类。当底层存储容器是自定义向量 (Vec) 时一切正常,但现在我遇到了一个我不明白的奇怪情况问题。
如果我通过显式调用 Str newStr("some words"); 之类的构造函数来创建一个新的 Str 对象,然后尝试使用 cin >> newStr; 覆盖它,程序最终会崩溃,当它到达 @987654327 时会在调试器中给出一个 SIGABRT @析构函数(就是delete[] data;)。
如果我创建一个新的空Str 然后使用cin 像Str newStr; cin >> newStr; 一样填充它,或者如果我使用cin 覆盖我使用Str newStr = "some words"; 创建的Str,则不会发生这种情况,它仅在我尝试覆盖通过显式调用非默认构造函数生成的Str 时才会失败,即使此类型在被覆盖之前正确显示。
如果我在创建/显示奇怪行为 Str 和使用 cin 更改其值之间不创建任何新的 Strs,那么在这种情况下,另一个奇怪的事情实际上可以正常工作。
Str a = "Here is a";
Str b("And here is b");
cout << a << endl << b << endl;
Str c = "Finally we have c";
cout << c << endl;
cin >> c;
cout << c << endl << endl;
cin >> b;
cout << b << endl;
这表明您可以成功覆盖Str c,但是当您尝试覆盖Str b 时会崩溃。但是,这可以让您覆盖 b 并且程序成功完成:
Str a = "Here is a";
Str b("And here is b");
cout << a << endl << b << endl;
cin >> b;
cout << b << endl;
Str 包含私有成员 char* data、int length, limit 并且用于 a 和 b 的构造函数是:
Str::Str(const char* cp) {
limit = length = std::strlen(cp);
data = new char[length];
for (size_type i = 0; i != length; ++i)
data[i] = cp[i];
}
我也有>>friended,它的实现是:
istream& operator>>(istream& is, Str& s) {
delete[] s.data;
s.length = s.limit = 0;
char c;
while (is.get(c) && isspace(c)) ;
if (is) {
do s.push_back(c);
while (is.get(c) && !isspace(c));
if (is)
is.unget();
}
return is;
}
我知道push_back 在这个类中可能是一个奇怪的功能,但即使使用cin 很长时间Str 需要很多push_backs,它也能正常工作。我已经尝试调整类/运算符的不同部分几个小时,但我很难过 o_O
最后,我不确定为什么在使用 Str newStr = "blah"; 语法的 Str 初始化期间没有调用我的复制 ctor(使用 couts 检查),即使它有效。
编辑,push_back:
void Str::push_back(char c) {
if (length == limit) {
limit = std::max(limit*2, 1);
char* newData = new char[limit];
for (size_type i = 0; i < length; ++i)
newData[i] = data[i];
delete[] data;
data = newData;
}
data[length++] = c;
}
【问题讨论】:
-
当您使用底层
std::vector时,内置了push_back()函数。现在您正在使用字符缓冲区,您必须编写自己的push_back()。看起来这很可能是错误所在。请在此处发布源代码。 -
当使用
Vec时,我还必须写push_back(),因为该练习涉及制作一个自定义类以像std::vector一样工作,编辑以显示我的Str::push_back(),似乎有效在其他情况下,当它被多次调用时,会覆盖Str someStr = "asdf";之类的东西 -
没有明显错误。如果可以发布整个源代码,我会将其粘贴在调试器中,看看会发生什么。
-
好的,谢谢!尝试一个源代码发布站点:sourcepod.com/vzhhel20-31086 一起编辑了 header/source/main 应该可以作为一个整体工作
-
刚刚发现与@Dietmar_Kühl 相同的东西。他比我快。 :-)