删除字符指针获取堆错误

Deleting a character pointer getting heap error

本文关键字:错误 获取 指针 字符 删除      更新时间:2023-10-16

下面的代码应该实现我自己的字符串类。类似于创建类似于String s = "Hi";的内容。当它进行销毁并到达delete[] data所在的部分时,我遇到了一个错误。Is表示当我超出堆缓冲区时我正在写作。这些不是cstring,所以在我的字符串末尾没有空字符。

这是我的转换/默认构造函数:

    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;

构造函数分配一个包含size元素的char数组。

然后,您的构造函数出现,将size+1字符复制到数组中(我假设getSize()返回size)。

因此,构造函数代码在数组的末尾运行,并在分配的数组末尾之后损坏一个字节。

附言:不需要static_cast,只会使代码更加模糊。

concat方法中的第一行:

String346 tempData(data);

将char*传递给未以null结尾的构造函数,因此对strlen的调用将经过字符串的末尾。

接下来的两行也不起作用:

   size = tempData.getSize() + catString.getSize();
   destroy();

destroysize设置回零,这意味着您的方法的其余部分将不执行任何操作。

你应该试着通过调试器运行它,并一步一步地完成它——然后你可以在每一步检查变量的值,并确保你的程序正在做你期望的事情。

此外,如果你有一个成员变量在析构函数中被释放,你应该研究"三条规则"或"五条规则",以确保它们不会被释放两次。