以下代码应该实现我自己的字符串类。与您创建类似String s = "Hi";
的内容类似。当它破坏并到达delete[] data
的部分时,我收到一个错误。当我离开堆缓冲区时,我正在写作。这些不是cstrings,因此我的字符串末尾没有空字符。
这是我的转换/默认构造函数:
String346::String346(const char * oldString) : data(NULL), size(static_cast<unsigned int>(strlen(oldString))){
data = new(std::nothrow) char[size];
for (unsigned int i = 0; i <= getSize(); i++){
data[i] = oldString[i];
}
}
由于这些函数需要支持函数链接,因此如果传递了String346
对象或者传递了char *
,我将把我的两个函数与我的问题相关联。
传递char *
的连接函数:
String346 & String346::concat(const char * catString) {
String346 newCatString(catString);
concat(newCatString);
return (*this);
}
传递String346
对象的连接函数:
String346 & String346::concat(const String346 & catString) {
String346 tempData(data);
size = tempData.getSize() + catString.getSize();
destroy();
data = new (std::nothrow) char[size];
if (data == NULL){
std::cout << "Not enough space to concatinate this string." << std::endl;
}
else{
unsigned int index = 0;
for (unsigned int i = 0; i < getSize(); i++){
if (i < tempData.getSize()){
data[i] = tempData.data[i];
}
else{
data[i] = catString.data[index];
index++;
}
}
}
return (*this);
}
我的破坏功能可以完成破坏物体的所有工作。它包含以下三行:
delete[] data;
data = NULL;
size = 0;
return;
答案 0 :(得分:1)
您的构造函数分配一个包含char
元素的size
数组。
然后,您的构造函数似乎将size+1
个字符复制到数组中(我假设getSize()
返回size
)。
因此,构造函数代码在数组末尾运行,并破坏分配数组末尾的一个字节。
P.S。不需要static_cast
,只会使代码更加模糊。
答案 1 :(得分:0)
concat
方法的第一行:
String346 tempData(data);
将char *传递给非null终止的构造函数,因此对strlen
的调用将超过字符串的结尾。
接下来的两行也不起作用:
size = tempData.getSize() + catString.getSize();
destroy();
destroy
将size
设置为零,这意味着您的方法的其余部分将不会执行任何操作。
您应该尝试通过调试器运行它并单步执行它 - 然后您可以在每一步检查变量的值,并确保您的程序正在按预期执行。
另外,如果你有一个在析构函数中释放的成员变量,你应该查看“三个规则”或“五个规则”,以确保事情不会被释放两次。