2016-03-20 9 views
0

Microsoft Visual Studio 2015を使用してC++で独自のStringクラスを作成しようとしました。このようなクラスを作成しました。メモリリークはありますか?

#include<string.h> 
class myString { 
    private: 
     char* content; 
    public: 
     int size; 
     myString(); 
     myString(char*); 
     ~myString(); 
     bool operator==  (const myString &) const; 
     bool operator!=  (const myString &) const; 
     myString operator= (const myString &); 
     myString operator+ (const myString &) const; 
     myString operator+= (const myString &); 
     friend std::ostream& operator<< (std::ostream &os, const myString &); 
     char operator[] (int &) const; 
}; 

std::ostream& operator<<(std::ostream &os, const myString &string) { 
    os << string.content; 
    return os; 
} 

myString::myString() { 
    size = 0; 
    content = "\0"; 
} 

myString::myString(char* newContent) { 
    size = strlen(newContent); 
    content = new char[size+1]; 
    strcpy(content, newContent); 
} 

myString::~myString() { 
    delete[] content; 
} 

myString myString::operator= (const myString &string) { 
    if (size != string.size) { 
     delete[] content; 
     size = string.size; 
     content = new char[size+1]; 
    } 
    strcpy(content, string.content); 
    return *this; 
} 

bool myString::operator== (const myString &string) const { 
    if (size != string.size) 
     return false; 
    if (strcmp(content, string.content)) 
     return false; 
    return true; 
} 

bool myString::operator!= (const myString &string) const { 
    if (*this == string) 
     return false; 
    return true; 
} 

myString myString::operator+ (const myString &string) const { 
    int newSize = size + string.size; 
    char* newContent = new char[newSize]; 
    strcpy(newContent, content); 
    strcat(newContent, string.content); 
    return myString(newContent); 
} 

myString myString::operator+= (const myString &string) { 
    *this = *this + string; 
    return *this; 
} 

char myString::operator[] (int &index) const { 
    return content[index]; 
} 

これを実行しようとするとうまくいきます。

#include<iostream> 
#include "MyString.h" 
using namespace std; 

int main() { 
    myString s("my new"); 
    cout << s+" string" << endl;  
} 

しかし、私はメモリから新しい領域を割り当てると私がreturn文return myString(newContent);でそれを必要とするchar* newContent = new char[newSize];ラインでoperator+関数内の任意のメモリリークがあるかどうかわかりません。

私はこの行の前に割り当てを解除することができず、return文の後に割り当てを解除することはできません。正しいですか、メモリリークがありますか?もしそうなら、私はこれをどのように修正できますか?

EDIT 1: 王子Dhaliwalの助けを借りて、次のように私はoperator+機能を変更しました。

myString myString::operator+ (const myString &string) const { 
    myString temp; 
    int newSize = size + string.size; 
    char* newContent = new char[newSize + 1]; 
    temp.size = newSize; 
    strcpy(newContent, content); 
    strcat(newContent, string.content); 
    temp.content = newContent; 
    return temp; 
} 

しかし、私はローカルtempを作成したので、それを返す前にそのデストラクタを呼び出し、エラーが発生します。私は一時的にもメモリを割り当てるべきだと思いました。私は次のように機能を変更しました。

myString myString::operator+ (const myString &string) const { 
    myString* temp= new myString; 
    int newSize = size + string.size; 
    char* newContent = new char[newSize+1]; 
    temp->size = newSize; 
    strcpy(newContent, content); 
    strcat(newContent, string.content); 
    temp->content = newContent; 
    return *temp; 
} 

は、今では正常に動作しますが、私は理由temp変数のメモリリークがまだあると信じています。メモリリークがある場合、これを修正する方法は?

EDIT 2: 私は単にあなたのコードでメモリリークが実際にあるコピーコンストラクタ

+0

あなたのコードをプロファイルすれば、メモリリークがあるかどうかを知ることができます。もしそうなら、あなたはどこで見つけることができます。 – ferit

+1

STLに文字列クラスがある場合、なぜこれを行うのですか? – duffymo

+0

これは私の宿題からのもので、私たちはそれらを使用することを禁じています。私は学習目的のために推測する。 –

答えて

0

を作成することによって、それを修正しました。 s + " string"+演算子を使用している場合。あなたのoperator+()定義すなわち

myString myString::operator+ (const myString &string) const { 
    int newSize = size + string.size; 
    char* newContent = new char[newSize]; 
    strcpy(newContent, content); 
    strcat(newContent, string.content); 
    return myString(newContent); 
} 

であなたは、ここにchar* newContent = new char[newSize];新しい文字列を割り当てる新しい文字列に古いと新しいパーツをコピーしています。もう一度、コンストラクタreturn myString(newContent);に新しい文字列を割り当てます。しかし、どこで古い文字列を削除していますか?そのコードはどこにもありません。したがって、文字列newContentを削除する必要があります。 あなたはコピーコンストラクタを作成する必要が この

myString myString::operator+ (const myString &string) const { 
    myString temp; 
    int newSize = size + string.size; 
    char* newContent = new char[newSize + 1]; 
    temp.size = newSize; 
    strcpy(newContent, content); 
    strcat(newContent, string.content); 
    temp.content = newContent; 
    return temp; 
} 

UPDATEを行うことができます。

myString(const myString &rhs) : 
size(rhs.size) { 
    content = new char[size + 1]; 
    strcpy(content, rhs.content); 
} 
+0

答えをありがとう!ところで、 '\ 0'文字のためにnewContentのメモリを割り当てるときにnewSize + 1を書くべきではありませんか? –

+0

さらに、temp文字列をローカルに作成しました。したがって、この演算子+関数が終了すると、tempのデストラクタが呼び出されます。私はこれをどのように扱うべきですか? –

+0

'temp 'のデストラクタが呼び出される前に、ローカル変数のコピーを返すときにコピーされます。 – 0x0001

関連する問題