문제

수업에 대한 포인터 벡터가 있습니다. 나는 그들의 소멸자에게 전화를 걸어 기억을 해제해야합니다. pointers vector.clear ()의 벡터이므로 작업을 수행하지 않으므로 수동으로 그렇게했습니다.

void Population::clearPool(std::vector<Chromosome*> a,int size)
{
    Chromosome* c;
    for(int j = 0 ;j < size-1;j++)
    {
       c = a.back();
       a.pop_back();
       delete c;
       printf("  %d \n\r",j);
       c = NULL;

    }

}

Printf는 세분화 결함이 발생하는 염색체를 볼 수있는 말하는 파괴자가 있기 때문에 있습니다. ClearPool ()이 호출되고 크기가 100이라고 말하면 0과 100 사이의 염색체에서 분할 결함을 줄 수 있습니다.

나는 왜 이것이 일어날 수 있는지 전혀 모른다. 나는 브레이크 포인트로 디버깅하는 동안 내가 보는 것이 무작위 염색체에서 그곳에서 일어난다는 것입니다.

CodeBlocks IDE 및 GDB 디버거를 사용하고 있습니다. 세분화 결함이 발생할 때 스택 추적에는 4 개의 메모리 주소와 기능이 있습니다. wsncpy().

도움이 되었습니까?

해결책

void Population::clearPool( std::vector <Chromosome*> & a )
{
   for ( int i = 0; i < a.size(); i++ ) {
      delete a[i];
   }
   a.clear();
}

벡터는 참조로 전달됩니다. 코드에서 벡터의 사본이 사용되므로 호출 프로그램에서 변경되지 않음을 의미합니다. 사본의 포인터를 삭제하기 때문에 원본의 포인터는 이제 모두 유효하지 않습니다. 게시 한 코드에 표시되지 않은 방식으로 유효하지 않은 포인터를 사용하고 있다고 생각합니다.

C ++ 라이브러리 알고리즘을 사용하는 몇 가지 템플릿 솔루션이 게시되었으므로 다음과 같은 템플릿 솔루션을 고려할 수도 있습니다.

template <class C> void FreeClear( C & cntr ) {
    for ( typename C::iterator it = cntr.begin(); 
              it != cntr.end(); ++it ) {
        delete * it;
    }
    cntr.clear();
}

이것을 사용하면 동적으로 할당 된 객체의 컨테이너를 제거 할 수 있습니다.

vector <Chromosome *> vc;
list <Chromosome *> lc;
// populate & use
FreeClear( lc );
FreeClear( vc );

다른 팁

약간 수정 된 버전 (@1800 정보).

  struct DeleteFromVector
    {
        template <class T>
        void operator() ( T* ptr) const
        {
            delete ptr;
        }
    };


std::for_each(aVec.begin(), aVec.end(), DeleteFromVector());

나는 당신이 왜 충돌하는지 모르겠지만, 한 가지 가능성은 벡터의 크기가 당신이 통과하는 크기와 같지 않다는 것입니다. 또한 0에서 크기 2로 반복되고 있습니다. 끝까지가는 것을 의미하지 않습니까?

관용 C ++를 사용하여 배열의 모든 항목을 삭제하는 한 가지 방법은 다음과 같습니다.

template<class T>
class deleter
{
  public:
    void operator()(const T* it) const
    {
      delete it;
    }
};

std::for_each(a.begin(), a.end(), deleter<Chromosome>());

Boost Lambda는 이미 포인터 시퀀스를 삭제하기위한 untctor를 가지고 있습니다.

std::for_each(a.begin(), a.end(), boost::lambda::delete_ptr());

벡터의 각 포인터가 다른 물체를 가리키는 것이 확실합니까? (즉, 두 포인터는 둘 다 같은 물체를 가리키지 않으므로 두 번 삭제하려고합니다.

이 방법을 호출하기 전에 포인터 중 일부를 삭제하지 않습니까? (즉, 목록의 각 포인터가 유효한 개체를 가리키는 것이 확실합니까?)

가장 큰 이유는 전화입니다 삭제 같은 주소에 대해 두 번. 벡터에 하나 이상의 객체를 추가하면 발생할 수 있습니다. 이 객체의 주소를 출력하는 일부 명령문을 삽입하려면 삭제.

printf( "will delete %d\n", (int)c );
delete c;

나는 문제를 발견했다.

그것은 가장 잘 숨겨져있었습니다 (어리석은 나이 가외의 다른 사람은) 그 장소가 될 수있었습니다.

일부 사람들은 유전자 알고리즘 프로그램이라고 생각했듯이. 제가 만들고있는 튜토리얼을위한 것입니다. 나는 내가 만든 룰렛 휠 기능에서 염색체의 크로스 오버 포인트를 무작위로 선택했습니다. 글쎄 ... 거기 안에는 -1이 없었습니다. 그것은 문자 그대로 모든 것을 파괴하고 결국 세분화 결함으로 이어졌습니다.

도와 주셔서 감사합니다.이 게시물에서 내가 따라야 할 정말 좋은 관행을 보았습니다.

원시 포인터 대신 스마트 포인터 (예 : Auto_ptr)를 사용하고 각 요소의 소멸자를 호출하는 벡터 :: 클리어 메소드를 사용하는 것이 좋습니다.

void Population::clearPool(std::vector<Chromosome*>& a)
{
    for(size_t i = 0; i < a.size(); i++) {
        delete a[i];
    }

    a.clear();
}

코드의 일부 포인터는 올바른 염색체 물체를 참조하지 않는 것 같습니다. 코드 결과로 일부 객체를 두 번 삭제하려고하면 다음과 같습니다.

Population p;
vector<Chromosome*> chromosomes;
p.clearPool(chromosomes,chromosomes.size()); // You pass by value, so chromosomes is not changed
p.clearPool(chromosomes,chromosomes.size()); // Delete already deleted objects second time

유용한 ptr_vector를 찾을 수 있습니다 포인터 컨테이너 라이브러리 부스트 비슷한 오류를 피하기 위해

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top