2012-01-13 1 views
0

Valgrind가 잘못된 읽기 오류를 감지했습니다. 수정 방법이나 정확한 방법을 모릅니다. 문제가 무엇인지 알 수 없습니다.Valgrind가 간단한 반복기 클래스에서 유효하지 않은 읽기 오류를 감지합니다.

Invalid read of size 8 
at 0x443212: std::vector<Tile*, std::allocator<Tile*> >::end() const 
by 0x44296C: Collection<Tile*>::Iterator::operator++() 

Iterator 클래스는 매우 간단하지만 (실제로는 다소 나쁜 프로그래밍 요소이지만) 지금 당장 필요합니다.

while (mY != mX->end() && *mY == 0) ++mY; 

... 반복자의 다음 Valgrind의 오류를 일으키는

Iterator(size_t x, size_t y, const TileCollection& tiles) 
     : mTiles(&tiles) 
     , mX(mTiles->begin()) 
     , mY(mTiles->at(x).begin()) 
{ 
     std::advance(mX, x); 
     std::advance(mY, y); 

     bool foundFirst = false; 

     while (!foundFirst) 
     { 
       while (mY != mX->end() && *mY == 0) ++mY; 

       if (mY != mX->end()) foundFirst = true; 
       else 
       { 
        ++mX; 

        if (mX != mTiles->end()) mY = mX->begin(); 
       } 
     } 
} 

Iterator Iterator::operator++() 
{ 
     bool foundNext = false; 

     ++mY; 

     while (!foundNext) 
     { 
       while (mY != mX->end() && *mY == 0) ++mY; 

       if (mY != mX->end()) foundNext = true; 
       else 
       { 
        ++mX; 

        if (mX != mTiles->end()) mY = mX->begin(); 
       } 
     } 

     return *this; 
} 

void TileCollection::add(Tile* tile) 
{ 
     Point2D p(tile->getPosition()); 

     std::vector<Tile*> tmp(1, (Tile*)0); 

     if ((size_t)p.x >= mTiles.size()) 
       mTiles.resize(p.x + 1, tmp); 
     if ((size_t)p.y >= mTiles.at(p.x).size()) 
       mTiles.at(p.x).resize(p.y + 1, (Tile*)0); 

     mTiles.at(p.x).at(p.y) = tile; 

     ++mNumTiles; 
} 

실제 코드 라인이있다 : 나는 희망이 내 문제를 찾을 수 있도록 당신이 알아야 할 세 가지 방법이 있다고 생각합니다 : : 연산자 ++ 메서드.

답변

1

그것은는 적어도, 나 그에게 적당한 다른 절을 부족 operator++

if (mX != mTiles->end()) mY = mX->begin(); 

에 다음 줄을 찾습니다.

mX이 실제로 mTiles->end()에 도달하면 어떻게되는지 고려하십시오. while 루프 while 루프의 새 반복을 입력합니다. 해당 루프 (Valgrind 오류가 발생하는 줄)의 첫 번째 줄은 mX->end()을 평가하므로 mX을 역 참조하려고 시도하지만 mXmTiles->end()입니다. 실제로 참조하지 않으므로 모음의 최종 반복자를 역 참조하는 것은 올바르지 않습니다 컬렉션의 요소. 이것이 내 Valgrind 오류의 원인 일 수 있다고 생각합니다.

은 (생성자는 본질적으로 같은 코드가 포함되어 있습니다.)

가 더 일반적으로, 나는 당신이 당신의 2 차원 배열의 끝에 도달 핸들 방법에 대해 생각해야합니다 생각합니다. Iterator 클라이언트가 반복의 끝에 도달했는지 여부를 어떻게 확인합니까? operator++이 2 차원 배열의 끝에 도달하면 어떻게 처리 할 것으로 예상합니까? 너무 자주 전화받는 것을 막아야합니까?

+0

감사합니다. 귀하의 대답은 정확합니다. 적절한 else 절을 ​​추가하면 문제가 해결됩니다. – BrightBit

0

당신은 오류가 발생한 곳을 찾아 얻을 위해 문을 분할하려고 할 수 있습니다

while (mY != mX->end()) // maybe here 
{ 
    if (*mY != 0) // maybe here 
    { 
     break; 
    } 
    ++mY; // maybe here 
} 

-fno-inline 당신이 추적하는 데 도움이 될 수 있습니다 더 좋은 스택 추적을 얻을하는 데 도움이 GCC 컴파일러 옵션을 사용하여 컴파일 오류. 또한 프로그램이 매우 느려지므로 나중에 제거하는 것을 잊지 마십시오.

+0

'std :: vector :: end()'에서 오류가 발생했기 때문에 "maybe here"라고 표시된 첫 번째 줄에서 오류가 발생하고 있다는 것이 현재 스택 추적에서 분명하지 않습니까? –