使用动态分配指针将运算符覆盖应用于类

时间:2017-03-23 09:14:03

标签: c++ pointers memory-corruption

我已经定义了MyString类,现在我想实现添加操作。发生内存泄漏很可怕,所以我已经处理了从析构函数中释放动态分配的指针。

#include <iostream>

class MyString {
private:
    int _size;
    char* _str;

public:
    MyString() {
        _size = 0;
        _str = nullptr;
    }

    MyString(int size, char* str) {
        _size = size;
        _str = new char[size + 1];
        strcpy(_str, str);
    }

    ~MyString() {
        delete[] _str;
    }

    void print() {
        std::cout << _str << std::endl;
    }

    friend MyString operator+(const MyString& lhs, const MyString& rhs);
};

MyString operator+(const MyString& lhs, const MyString& rhs) {
    char* temp = new char[lhs._size + rhs._size + 1];
    strcpy(temp, lhs._str);
    strcat(temp, rhs._str);

    MyString ret(lhs._size + rhs._size, temp);
    delete[] temp;
    return ret;
}

int main() {
    MyString first(5, "first");
    MyString second(6, "second");
    MyString add = first + second;

    first.print();
    second.print();
    add.print();
}

但是,如果我编译代码并运行它,first.print()second.print()打印得很好,但add.print()将打印垃圾值,然后崩溃(调试断言失败! )。

输出:

first
second
硼硼硼硼硼硼硼硼?흚 (and creashes :(.. )

如果我注释并运行析构函数,它打印效果很好,但会发生内存泄漏。为什么会这样?我已经看过几个运算符覆盖的例子,但我还没有找到这个动态分配指针的例子。

任何建议都将受到高度赞赏!

2 个答案:

答案 0 :(得分:2)

MyString operator+(const MyString& lhs, const MyString& rhs) {
    char* temp = new char[lhs._size + rhs._size + 1];
    strcpy(temp, lhs._str);
    strcat(temp, rhs._str);

    MyString ret(lhs._size + rhs._size, temp);
    delete[] temp;
    return ret;
}

在此函数结束时,“ret”被销毁,它调用析构函数并删除缓冲区。返回的是从'ret'复制的MyString的新实例,其缓冲区指向与原始内存相同的内存位置。由于这已被删除,您现在打印出垃圾。

要解决此问题,您可以添加复制构造函数以确保复制缓冲区:

class MyString {

// Other class details
public:
    MyString(const MyString & other) : MyString(other._size, other._str) {}

// Other class details
}

这将确保在将一个MyString分配给另一个MyString时复制缓冲区。

答案 1 :(得分:0)

#include<iostream>

using namespace std;
class Mystring{

private:
    int size;
    char *str;

public:
    friend Mystring operator*(const Mystring &a, const int &d);
    friend Mystring operator+(const Mystring &a, const Mystring& b);

    friend ostream& operator << (ostream &os, const Mystring a);
    friend istream& operator >> (istream &is, const Mystring a);


Mystring (int a, char b) {
    this->size = a;
    this->str = new char(a);
    for (int i = 0; i < a; i++) {
        this->str[i] = b;
    }
}
~Mystring() {}

};

Mystring operator+(const Mystring &a, const Mystring& b) {

Mystring  c(a.size + b.size, { 0 });
for (int i = 0; i < a.size; i++)
{
    c.str[i] = a.str[i];
}
for (int i = 0; i < b.size; i++)
{
    c.str[a.size + i] = b.str[i];
}
return c;
}
Mystring operator*(const Mystring& a,const int &d){

int z = a.size*d;
Mystring c(z, { 0 });
int k=0;
for (int j = 0; j < d; j++)
{
    for (int i = 0; i < a.size; i++)
    {
        c.str[k+i] = a.str[i];

    }
    k = a.size + k;
}
return c;
}

ostream& operator << (ostream &os, const Mystring a) {

os << "[";

int i;
for ( i = 0; i < a.size; i++)
{
    os << a.str[i];
}

os << "]";
return os;
}
istream& operator >> (istream &is, const Mystring a) {

for (int i = 0; i < a.size; i++)
{
    cout << i << "번째 문자 : ";
    is >> a.str[i];
}
return is ;
}


int main()
{
int aSize, bSize, iter;
char aInit, bInit;

cout << "문자열A의 크기와 초기문자를 입력: ";
cin >> aSize >> aInit;
Mystring str1(aSize, aInit);
cout << str1 << endl;

cout << "문자열A 입력" << endl;
cin >> str1;
cout << str1 << endl;

cout << "문자열B의 크기와 초기문자를 입력: ";
cin >> bSize >> bInit;
Mystring str2(bSize, bInit);
cout << str2 << endl;

cout << "문자열B 입력" << endl;
cin >> str2;
cout << str2 << endl;

cout << "문자열A와 문자열B 합치기 : ";
Mystring str3 = str1 + str2;
cout << str3 << endl;

cout << "문자열A 반복횟수 입력 : ";
cin >> iter;
Mystring str4 = str1*iter;
cout << str4 << endl;

}

enter code here

为什么错误 〜MyString的(){}