2017-03-23 7 views
1

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 :(..) 

내가 주석과 소멸자를 실행하면 잘 인쇄하지만, 메모리 누수가 발생합니다. 왜 이런 일이 일어나는 걸까요? 연산자 오버라이드의 몇 가지 예를 살펴 보았지만이 동적 포인터 할당의 예는 발견하지 못했습니다.

모든 의견을 매우 높이 평가할 것입니다!

+4

[3, 5 및 0의 규칙] (http://en.cppreference.com/w/cpp/language/rule_of_three)에 대해 알아야합니다. 3 가지 규칙을 구현하면 문제를 해결하는 데 충분합니다. –

+0

감사! 기본 복사 생성자를 추가하면 매력처럼 잘 작동합니다. – youngminz

답변

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'에서 복사 된 MyString의 새로운 인스턴스이며, 버퍼의 버퍼 위치는 원본과 동일한 메모리 위치를 가리 킵니다. 이것은 삭제되었으므로 이제 쓰레기를 출력하고 있습니다.

는 버퍼를 복사하기 위해 복사 생성자를 추가 할 수 있습니다이 문제를 해결하려면 다음

class MyString { 

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

// Other class details 
} 

이 하나 MyString의 다른 MyString에 할당 할 때 버퍼가 복사됩니다 보장합니다.

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에가() {} 소멸자 호출하는 파괴 '마지막 ret'이 함수의 끝에

+0

스택 오버플로에 오신 것을 환영합니다! 이 질문은 작업 코드에 대한 설명이 아닌 * 설명 *을 찾고 있습니다.이 코드는 제대로 작동하지 않습니다. 중요한 'delete []'를 제거했기 때문에 누출됩니다. 귀하의 답변은 질문자에 대한 통찰력을 제공하지 않으며 삭제 될 수 있습니다. 관찰 된 증상의 원인을 설명하기 위해 [편집]하십시오. –