2010-07-18 4 views
0

여러분, 내 마지막 질문에 많은 도움이 되었으니 다시 시도해 보겠습니다. 이것은 숙제이고 마지막 하나는 꽤 오래되었지만 제출되었고 표시되기를 기다리고 있습니다. 그래서 저를 물릴만한 것이 있다면 그것은 아마도이 문제 일 것입니다. 클래스 이름 등을 모호하게 만들었으므로 과제를 제출할 수 있습니다 (다른 학생에게).istream_iterator 누설 메모리

나는 유일한 멤버가 Object에 대한 포인터 인 클래스가 있습니다. 이 클래스는 현재 보유하고있는 포인터로부터 특정 작업을 노출하도록 구성됩니다. 기본 클래스 인 Object *o_Object{1, 2, 3, ...}입니다. 이제 메모리 누수 나 충돌없이 다음 작업을 수행 할 수 있습니다.

std::vector<ObjectPtr> v; 
v.push_back(ObjectPtr(new Object1(..., ..., ...))); 
v.push_back(ObjectPtr(new Object2(..., ...))); 
v.push_back(ObjectPtr(new Object1(.., .., ..))); 

// Copy Constructor Ptr 
std::vector<ObjectPtr> v2(v); 
// Assignment Operator Ptr 
std::vector<ObjectPtr> v3; 
v3 = v2; 

이 모든 것이 작동하며 메모리 누수가 없습니다. 그러나 istream_iterator<ObjectPtr>이있는 파일의 내용을 읽으려고하면 누출되기 시작합니다. ObjectPtr은 동적 메모리를 처리하는 유일한 클래스이고 Object *o_은 NULL로 설정되거나 Object{1, 2, 3, ...}으로 할당됩니다. 읽을 수

파일의 모습이

 
Object1 
... 
... 
Object2 
... 
... 
Object1 
.. 
std::ifstream is("file.txt"); 
std::istream_iterator<ObjectPtr> in(is), end; 
for (; in != end; ++in) 
    cout << *in << "\n"; 

그것이 나에 unicorning 시작 여기 어딘가에

friend istream &operator>>(istream &is, ObjectPtr &op) { 
    std::string tmp; 
    while (std::getline(is, tmp)) { 
     if (tmp == "Object1") { 
      op.o_ = new Object1; 
      return is >> (Object1 &)*(op.o_); // Send it to operator>> for Object1 
     } 
     if (tmp == "Object2") { 
      op.o_ = new Object2; 
      return is >> (Object2 &)*(op.o_); 
     } 
     ... 
    } 
    return is; 
} 

처럼이 값을 읽는 데 사용 ObjectPtr의 친구 기능이 보인다, 왜 그런지 정말 알고 싶습니다.

요약하면 - 할당 및 복사 생성자가 올바르게 작동하는 동안 istream_iterator가 메모리를 누설하므로 클래스 Object{1, 2, 3, 4, ..}이 올바르게 구성되었고이 문제는 operator>> 안에 있습니다.

답변

2

다음은 나에게 발생한 첫 번째 문제입니다. op.o의 이전 값에 무슨 일이 마지막 줄에서

friend istream &operator>>(istream &is, ObjectPtr &op) { 
    std::string tmp; 
    while (std::getline(is, tmp)) { 
     if (tmp == "Object1") { 
      op.o_ = new Object1; 

: 나는 당신을 위해 사냥하고있는 문제인지 몰라?
개체로 스트리밍한다는 것은 완전히 구성된 개체로 스트리밍하는 것을 의미하며 개체의 이전 데이터를 염두에 두어야한다는 것을 기억하십시오. (종종 std::istream을 복용 생성자를 선호하는 이유입니다. 바로 다음 순간에 변경할 수있는 객체의 초기화를 금고 복잡한 객체의 경우.)

ObjectPtr는 할당 연산자 또는 swap() 멤버 함수가 있습니까? 그렇다면 새 오브젝트를 구성하여 입력 연산자를 구현하고 op을 사용하여 오브젝트를 할당/스왑하는 것이 더 쉬울 수도 있습니다.

+0

오, 남자 .. 당신은 내 하루를 보냈습니다 - op.o_를 삭제하십시오; 고마워, 고마워, 고마워! – citizencane

+0

@citizencane : 다른 많은 장소에서 여전히'o' 회원을주의해야합니다. 배정은 어떨까요? 복사 건설? 정말로, 나는 동적으로 할당 된 객체를 수동으로 만지작 거리는 모든 코드를 복제하는 것보다는 다른 멤버 (필자가 대답으로 쓴 것처럼)에서 연산자 >>()를 구현하려고합니다. – sbi

+0

이것에 대해 다시 생각해 보면 ObjectPtr이 두 클래스로 분리 될 수 있습니다. (적어도) 두 가지 일을하기 때문에 (A) 동적으로 할당 된 객체를 관리하고 (B)이 객체를 처리 할 때 프록시 역할을합니다. 목적. (A)를 적합한 스마트 포인터 클래스로 분리하면 (B) 구현이 훨씬 쉽고 간결 해집니다. – sbi