【问题标题】:Created my own string class -- errors with overloaded assignment operator and destructor创建了我自己的字符串类——重载赋值运算符和析构函数的错误
【发布时间】:2013-04-05 10:55:17
【问题描述】:

创建了我自己的字符串类,它在调用重载赋值运算符时意外中断(即我相信)。它在调用重载赋值运算符后尝试删除 mStr 时正好中断。

被删除的 mStr 是 "\nPlatinum: 5 \nGold: 5 \nSilver: 6 \nCopper: 5 "

我做错了什么,如何确保我的程序不会因没有内存泄漏而中断??

此处代码中断

String::~String()
{
delete [] mStr;
mStr = nullptr;
}

代码在此之前中断

    String tempBuffer;

    //Store entire worth of potions
    tempBuffer = "Platinum: ";
    tempBuffer += currencyBuffer[0];
    tempBuffer += "\nGold: ";
    tempBuffer += currencyBuffer[1];
    tempBuffer += "\nSilver: ";
    tempBuffer += currencyBuffer[2];
    tempBuffer += "\nCopper: ";
    tempBuffer += currencyBuffer[3];

    mCost = tempBuffer;

重载赋值运算符

String &String::operator=(const String & rhs)
{
//Check for self-assignment
if(this != &rhs)
{
    //Check if string is null
    if(rhs.mStr != nullptr)
    {
        //Delete any previously allocated memory
        delete [] this->mStr;

        //Deep copy
        this->mStr = new char[strlen(rhs.mStr) + 1];
        strcpy(this->mStr, rhs.mStr);
    }
    else
        this->mStr = nullptr;
}

//Return object
return *this;
}

重载的添加和赋值运算符

String &String::operator+=( String rhs)
{
//Check for self-assignment
if(this != &rhs)
{
    //Convert to cString
    char * buffer = rhs.c_str();

    //Find length of rhs
    int length = strlen(buffer);

    //Allocate memory
    char * newSize = new char[length + 1];

    //Copy into string
    strcpy(newSize, buffer);

    //Concatenate
    strcat(this->mStr, newSize);

    //Deallocate memory
    delete [] newSize;

}

//Return object
return *this;
}

复制构造函数

String::String(const String & copy)
:mStr()
{
*this = copy;
}

字符串构造函数

String::String(char * str)
{
//Allocate memory for data member
mStr = new char[strlen(str) + 1];

//Copy str into data member
strcpy(mStr, str);
}

字符的字符串构造函数

String::String(char ch)
{
//Assign data member and allocate space
mStr = new char[2];

//Assign first character to the character
mStr[0] = ch;

//Assign second character to null
mStr[1]= '\0';
}

【问题讨论】:

  • 制作字符串类是硬件,但这是唯一的方向。这是UML,构建一个字符串类。所有的代码都是我的。它是使用我们自己的字符串类来构建我们整个学期都必须构建的 RPG。
  • 默认构造函数的定义是什么?
  • 默认构造函数的定义是 String::String() :mStr() {} 编辑:如何在注释部分制作代码块? ``'s 对我不起作用。
  • 在单独的类中处理缓冲区的内存管理,例如使用std::vector,或您自己的buffer 类和resize 方法。然后在你的字符串类中编写你漂亮的运算符。将低级内存管理与一堆高级运算符重载混合是一个坏主意,并且会导致错误。

标签: c++ memory-leaks destructor


【解决方案1】:
  • 如果rhs 包含nullptr,则this->mStr 分配给nullptr 而不分配delete[]operator=() 中可能存在内存泄漏。
  • operator+=() this->mStr 在连接之前没有被扩展。这意味着strcat() 将写入不应写入的内存,从而导致未定义的行为,并且可能是析构函数中出现问题的原因。

【讨论】:

  • 所以你是说我没有为此分配空间->mStr??所以` //为newSize分配空间 this->mStr = new char [strlen(newSize) + 1];`
  • @gongzhitaao,因为delete[] nullptr是空操作,所以没必要。
  • 如果this->mStr = new char[strlen(rhs.mStr) + 1]; 抛出 this->mStr 丢失并且类将处于无效状态。也许他应该使用this->mStr的本地副本并在确保一切正常后删除。
  • @MrPickle5,在operator+() 中,this->mStr 必须足够大以容纳当前内容和传入内容。分配一个足够大的新缓冲区,将两者都复制到其中,删除 mstr 并将 mstr 分配给新缓冲区。
【解决方案2】:

我假设这是一个练习(否则你会使用std::string)。您的问题似乎是 operator+= 仅为您要添加的字符串分配足够的空间,没有为原始字符串和您追加到其末尾的新部分分配足够的空间。您需要分配更多空间:char * newSize = new char[strlen(this->mStr) + length + 1];,然后删除旧的字符串指针并将newSize 指针分配给类成员。

【讨论】:

  • 非常感谢。不幸的是,当它调用析构函数删除 tempBuffer 时,它仍然会中断。我添加了您的代码,删除了 newSize,然后分配了 newSize 指针。 newSize = this->mStr.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-10
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 2013-02-08
  • 2014-04-05
相关资源
最近更新 更多