2012-02-14 5 views
1

새 ModelImages 세트를 벡터에 추가하려고하는데 디버그 어설 션 오류, _BLOCK_TYPE_IS_VALID (pHead-> nBlockUse) 오류가 발생합니다. 이것은 생성 된 두 번째 ModelImage를 삭제하려고 할 때 발생합니다. 다음과 같이 삭제시 C++ 메모리 오류가 발생했습니다. - 디버그 어설 션 오류가 발생했습니다.

std::vector<ModelImage> ModelImages; 

for(int n=0;n<nParamSets;n++) 
{ 
    ModelImage* mI = new ModelImage(MOD_WIDTH,MOD_HEIGHT); 
    ModelImages.push_back(*mI); 
    delete mI; 
} 

생성자와 소멸자

, 복사 및 스왑 funcitons은 다음과 같습니다

ModelImage(int _width, int _height) 
{ 
    width = _width; 
    height = _height; 
    nPixels = width*height; 
    distance = new float[nPixels]; 
    intensity = new float[nPixels]; 
    derivX = new float[nPixels]; 
    derivY = new float[nPixels]; 
    maxDistance = 0.0f; 
    minDistance = 0.0f; 
} 

~ModelImage() 
{ 
    delete [] derivX; 
    delete [] derivY; 
    delete [] distance; 
    delete [] intensity; 
} 

ModelImage& operator=(ModelImage other) 
{ 
    swap(*this, other); 
    return *this; 
} 

friend void swap(ModelImage& first, ModelImage& second) 
{ 
    using std::swap; 
    swap(first.derivX,second.derivX); 
    swap(first.derivY,second.derivY); 
    swap(first.distance,second.distance); 
    swap(first.intensity,second.intensity); 

    swap(first.nPixels,second.nPixels); 
    swap(first.width,second.width); 
    swap(first.height,second.height); 
} 

그냥 벡터 ModelImages보고, 두 번째 ModelImage을 삭제하려고 전에 보여 그에서 두 ModelImages 벡터는 distance, intensity, derivX, derivY 배열에 대해 동일한 할당 된 메모리 주소를가집니다.

감사합니다. 감사합니다.

+0

여기에 복사 생성자가 있으며 방금 여기에 포함되었습니다. – 3Pi

+0

업데이트에 복사 생성자가 표시되지 않습니다. 'ModelImage (ModelImage const & other);와 같은 형태의 시그니처를 가졌을 것입니다. –

+0

명시 적으로 지적 해 주셔서 감사합니다. 복사 및 관용구의 복사 부분을 구현하지 않았다는 것을 깨닫지 못했으며, 나는 가지고 있었다. 처음으로 그들과 함께 일했습니다. – 3Pi

답변

1

먼저 복사 생성자가 정의되어 있지 않아야합니다. 벡터 'push_back은 기본 복사본으로 사용자의 ModelImage을 구성하며, 단순히 구성원 포인터를 복사하지만 해당 포인터가 가리키는 메모리는 재 할당하지 않습니다. 그러나 이러한 참조는 원래 개체가 삭제 된 후에 사라집니다.

힌트 :

ModelImage(const ModelImage& orig) { 
    // appropriately reinitialize from orig 
} 

(당신이 바로 던져 경우) 왜 동적 어쨌든이 ModelImage의를 작성해야합니까 할당 operator==

와 혼동하지 : 복사 생성자는 같은입니까? new float[nPixels] 대신 vector<float>(nPixels)을 가져 가려면 어떻게해야합니까?

+0

ModelImage mI (MOD_WIDTH, MOD_HEIGHT)를 사용해 동적으로 생성하기; ModelImages.push_back (* mI); 그리고 그것도 작동하지 않았다. – 3Pi

+0

'ModelImages.push_back (ModelImage (MOD_WIDTH, MOD_HEIGHT));를 시도해 보셨습니까? 하지만 그걸로 복사 생성자 중 하나를 사용하여 문제를 해결하지 않습니다 ... – moooeeeep

2

아마도 복사 생성자가 없기 때문일 수 있습니다.

포인터가 참조하는 메모리의 복사본을 만드는 복사본 생성자를 만듭니다.

표준 컨테이너를 사용하는 경우 일반적으로 삽입 할 때 개체 사본을 만듭니다. 복사 생성자가 없으므로 멤버 포인터는 단순히 데이터의 복사본을 만들고 있기 때문에 동일한 메모리 주소를 가리키게됩니다. 임시 복사본 중 하나가 파괴되면 (또는 삽입 후 원래 개체에서 delete를 호출하면) 삽입 된 개체의 메모리에 메모리가 삭제됩니다.

0

그것은 당신이 다음과 같은 멤버에 대한 적절한 복사 생성자와 할당 연산자를 가지고 있는지 여부를 게시 한 것과 분명하지 않다 :

distance 
intensity 
derivX 
derivY 

그렇지 않으면, 당신이 그 필요합니다. 자세한 내용은 Rule of three (C++ programming)을 참조하십시오.

더 나은 대안은 해당 데이터 멤버에 std::vector<double>을 사용하는 것입니다. 그렇게하면 복사, 할당 및 파기가 모두 자동으로 처리됩니다. 당신은 여전히 ​​적절한 수의 요소를 갖도록 구성하려고합니다.

0

클래스의 포인터로 정의 된 모든 배열이 있다고 가정합니다. 기본 복사본은 포인터의 값을 복사하여 외부 함수에서 포인터를 삭제할 때 밑줄이있는 메모리를 삭제합니다.제안

그냥 몇

-Utilize 벡터 대신 플로트 *의 표준 : : 벡터를 복사하여 정의 된 이동 생성자

allread 년 - 루프가 전혀없는 저장소를 사용하지 않아도이의 가치 의미론 및 대처법이 완벽하게 지원되며 오류가 발생하기 쉽습니다.

for(int n=0;n<nParamSets;n++) 
{  
    ModelImages.push_back(ModelImage(MOD_WIDTH,MOD_HEIGHT)); 
} 
관련 문제