2013-04-01 2 views
0

내 코드에 문제가 있습니다. BLOCK_TYPE_IS_VALID의 오류가 발생했습니다. 새로운 기능 및 삭제 기능에 문제가 있음을 알고 있지만 찾을 수 없습니다. 나는 이러한 기능을 가진 MyString의 클래스가 있습니다힙 및 클래스 소멸자

//constructors and destructors 
myString::myString() { 
    this->string_ = NULL; 
    this->length = 0; 

    cout << "created " << "NULL" << endl; 
} 

myString::myString(char a[]) { 
    int i; 
    for (i=0; a[i]!=NULL; i++); 
    this->length = i; 

    int j=0; 
    while(pow(2,j)<i) 
     j++; 

    this->string_ = new char [(int)pow(2,j)]; 
    for (int i=0; i<this->length; i++) 
     this->string_[i] = a[i]; 

    cout << "created " << this->string_ << endl; 
} 

myString::~myString() { 
    cout << "deleteing " << this->string_ << endl; 
    if (this->string_ != NULL) 
     delete [] this->string_; 
} 

을 나는이

myString a("aaa"); 
myString b("bbbb"); 
myString c; 
c = a + b; 
cout << c.get_lenght() << endl; 
cout << c.get_string() << endl; 

을 실행할 때 나는 줄 "C = A + B"에서 오류가 발생하고 프로그램이 중지됩니다.

+1

클래스에 '연산자 +'를 정의해야 프로그램에서 문자열을 추가하는 방법을 알 수 있습니다. – Caesar

+1

연산자'+'& operator'='를 과부하 시켰습니까? 그 코드를 보여줄 수 있습니까? – user93353

+1

내가 본 코드를 기반으로 복사 생성자와 대입 연산자를 정의했기를 바랍니다. 그 코드를 보여줄 수 있습니까? –

답변

1

,하지만 당신 같은데요 Rule of Three을 따라 가지 않았습니다.

제대로 구현 된 복사 생성자 및 복사 할당 연산자가 없으면 개체를 안전하게 복사 할 수 없습니다. 기본 구현은 단순히 포인터 (및 다른 멤버 변수)를 복사하여 두 복사본을 모두 소멸자의 동일한 메모리 블록을 삭제하도록 남겨 둡니다.

가장 간단한 해결책은 메모리 관리를 위해 설계된 클래스를 사용하는 것입니다. std::string 또는 std::vector<char>이 이상적입니다. 또한 고려 이동 생성자와 할당 연산자를 제공하고, 더 많은 보너스 포인트, C++ 11에서

// Copy constructor 
myString(myString const & other) : 
    string_(new char[other.length]), 
    length(other.length) 
{ 
    std::copy(other.string_, other.string_+length, string_); 
} 

// Simple assignment operator 
// For bonus points (and a strong exception guarantee), use the copy-and-swap idiom instead 
myString & operator=(myString const & other) { 
    if (this != &other) { 
     delete [] string_; // No need to check for NULL (here or in the destructor) 
     string_ = new char[other.length]; 
     length = other.length; 
     std::copy(other.string_, other.string_+length, string_); 
    } 
    return *this; 
} 

:

메모리를 직접 관리하는 당신이 좋은 이유가 가정, 당신은 뭔가를해야합니다 . 이것들은 포인터를 수정할 필요가 있으므로 복사하는 것보다 훨씬 효율적입니다.

+0

고맙습니다. 코드에서 많은 것을 배웁니다. – Ramyad

3

클래스에 copy constructorassignment operator을 정의해야합니다.

그렇지 않으면 rule of three을 위반합니다.

이 코드 ...

c = a + b; 

가 발생할 수 있습니다 임시 myStringa + b를 들고.

기본 생성 된 복사 및 할당 구현은과 동일한 string_ 포인터와 동일한 c포인터를 제공합니다.

그런 문자열 중 하나의 소멸자가 실행될 때 다른 문자열에는 매달린 포인터가 있습니다.

공교롭게도,이 코드 :

if (this->string_ != NULL) 
    delete [] this->string_; 

단순히 다르게 행동하지 않습니다 : 당신은 클래스 정의를 표시하지 않은

delete [] this->string_; 
+0

고맙습니다, 저는 매우 혼란 스러웠습니다. 이제 나는 무슨 일이 일어나는 지 이해합니다. – Ramyad