2011-09-12 4 views
0

이것은 C++ 연산자 오버로딩을 연구하기 위해 코딩 한 간단한 예제입니다. 코드를 실행하면 코드 c = a + b에 멈 춥니 다. 그리고 나는 그것이하여 HelloWorld를 출력 않습니다 할당 연산자 오버로드 기능에 cout << ptr << '\n';를 넣으면 제어는 결코 디버깅의 일환으로 c.display();이 코드가 위에서 언급 한 장소에서 멈추는 이유는 무엇입니까?

에 도달하지 않기 때문에 문자열의 형식이 잘못 될 것 같지 않습니다.

왜 그 때 걸려 있습니까? 나는 무엇이 없는가 ??

class mystring 
{ 
    char *ptr; 

    public: 

    mystring(char *str = "") 
    { 
     ptr = new char[strlen(str) + 1]; 
     strcpy(ptr,str); 

    } 

    mystring operator +(mystring s) 
    { 
     char *str = new char[strlen(ptr) + strlen(s.ptr) + 1];//where should this memory be freed 
     strcpy(str,ptr); 
     strcat(str,s.ptr); 
     return mystring(str); 
    } 

    void operator =(mystring s) 
    { 
     strcpy(ptr,s.ptr); 

     //cout << ptr << '\n'; \\Debug - this prints out HelloWorld but still hangs 
    } 

    void display() 
    { 
     cout << ptr << '\n'; 
    } 

    ~mystring() 
    { 
     delete [] ptr; 
    } 
}; 

int main() 
{ 
    mystring a="Hello",b="World",c; 

    c = a + b; 

    c.display(); 

    getchar(); 

} 

편집 : 컴파일러 : MS-비주얼 C++ 2010 익스프레스/윈도우.

+0

'운영자 :

c.constructor() c.operator=(a.operator+(b)); 

및 운영자를 = 당신이 필요로하는 것은 메모리를

void operator =(mystring s) { // ptr is allocated enough memory for "", i.e. one byte strcpy(ptr,s.ptr); // copying more than one byte into one byte array //cout << ptr << '\n'; // this works, but you've trashed memory with the strcpy } // stack might be corrupted here, depends where this is, so execution can end up anywhere 

을 할당 실패

c = a + b; 

이 (가) 다음을 수행 '는 메모리를 할당하지 않습니다. 'operator +'는 두 번 할당합니다. –

+0

나는 또한 적절한 복사 생성자를 구현해야한다고 덧붙인다. – Nim

+0

valgrind와 같은 메모리 프로파일 러는 이런 종류의 메모리 오류를 발견했을 것이다. – Francois

답변

1

나는 당신이 얻는 것은 메모리 오류라고 생각합니다.이 줄 =

void operator = (mystring &s) // reference! 
{ 
    delete [] ptr; 
    ptr = new char [strlen (s.ptr + 1)]; 
    strcpy (ptr, s.ptr); 
} 
+1

또는 'tempPtr = new char [strlen (s.ptr + 1)]; strcpy (tempPtr, s.ptr); 스왑 (ptr, tempPtr); delete tempPtr;'[강력한 예외 보장] 제공 (http://en.wikipedia.org/wiki/Exception_guarantees). –

+0

@Skizz - 감사합니다. 그것은 작동하지만 destructor 함수에서 delete ptr을 주석 처리하는 경우에만 작동합니다. 어떤 생각이든이 일이 일어날 수 있습니다. 그것은 ptr이 이미 operator =()에서 해제되었거나 삭제 되었기 때문에입니까? 그렇다면 그 수정은 무엇입니까? – goldenmean

+0

@ goldenmean : 문자열을 복사하는 대신 어딘가에서'ptr' 값을 복사했기 때문일 것입니다. 'operator +'는 결과를 값으로 반환하므로 복사 및 삭제가 수행되므로'ptr'가 두 번 삭제됩니다. 'operator ='와 똑같은'mystring (const mystring & source)'구조체를 추가해보십시오. 'ptr'을 삭제 한 후에 다시 '0'으로 설정해야 다시 삭제해도 문제가 발생하지 않습니다. – Skizz

1

operator=이 고장났습니다. strcpy을 수행하기 전에 충분한 메모리를 적절히 할당하지 않았습니다. 이로 인해 정의되지 않은 동작이 발생합니다.

1

* CHAR STR = 새 문자 [나 strlen (PTR) + 나 strlen (s.ptr) + 1]; //이 메모리 소멸자 풀려

메모리를 해제 할 위치 .

연산자 = 당신이 할당 된 메모리를 해제하고 다시

+1

실제로는 강조한 특정 행은'operator +'에 있으므로 해당 함수에서 정리해야합니다. 두 번째 요점은 정확하지만 ... – Nim

+0

죄송합니다, 내 잘못. 물론 메모리는 메소드에서 해제되어야합니다. – Ilmirus

0

연산자를 할당해야 = 기존의 버퍼를 확보하고 생성자에서처럼 다음 새로 할당해야합니다.

0

는 코드는 c.display()을 타격하기 전에 차단 만들 것이다 명백한 문제가하지 않는 것,하지만 그렇게처럼 그것은 을 보일 수 있습니다.

작업 cout << ptr << '\n';은 스트림을 플러시하지 않으므로 나중에 출력이 캐싱 될 수 있습니다. 전체 프로그램이 이고 기본적으로이 완료되어 사용자가 getchar()에 문자를 입력하기를 기다리는 경우 일 수 있습니다.

디버거에서 코드를 실행하거나 출력을 cout << ptr << endl;으로 변경해보십시오.

현재 : operator+에 메모리가 누수되어 있으며 처리해야합니다. 나는 당신이 이미 그것을하는 방법에 대해 물었다는 것을 알고 있습니다, 당신은 제안 된 해결책을 좋아하지 않았거나 이해할 수 없었을 것입니다. 그러나 그대로 두는 것은 해결책이 아닙니다.

operator=은 전체 문자열을 담을 수있는 충분한 공간이 있는지 확인하지 않아서 정의되지 않은 동작을 유발할 수 있습니다.

관련 문제