2014-08-31 1 views
3

내 프로그램에서 점을 반복하여 화면에 무언가를 그려야하는 vector<Points*> points; (모두 고유 한 Pointssize: 6)이있었습니다. 그러나 새로운 요구 사항에 따라 벡터의 길이를 size: 14으로 늘려야합니다. 추가 할 수 있었다포인터의 이중 삭제 방지

새로운 항목은 이전 6Points에서 일했다, 그래서 대신 새로운 메모리를 할당, 나는 다음과 같이 바로 이전 포인터를 사용하여 생각 :의 소멸자에서

while (currentSize < 14){ 
    int rndPoint = getRandomPoint(0, 5); //random index to choose from the vector 
    points->push_back(points[randPoint]); 
} 

을 내가 특별히 할 때 (루프에서 액세스 위반 오류를 받고 있어요 - 내가 프로그램을 종료하려고 할 때, 그러나

for(int i=0;i<points.size(); ++i){ 
    if(points[i] != NULL){ 
    delete (points[i]); 
    } 
} 

: 나는 메모리 할당을 해제했습니다 때 클래스는, 나는 다음과 같은 일을 해요 i 색인 6에 도달). delete을 사용하여 6 개의 고유 점을 이미 삭제 한 경우 if (points[i] != NULL) 인 이유는 i=6,7...13 인 경우 true이되는 이유는 무엇입니까?

+0

'delete '뒤에'points [i] = NULL;'을 설정하면 자동으로 실행되지 않습니다. 또한 수업이 [규칙 3] (http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three)을 준수하는지 확인하십시오. –

+0

@ πάνταῥεῖ 그건 질문에 관한 것이 아닙니다. –

+0

@ πάνταῥεῖ 그것은 충분하지 않습니다. 'points [] '요소 중 일부는 이전 요소와 동일하고, ergo double delete입니다. –

답변

4

삭제에 의해 동일한 메모리에 대한 다른 참조가 nullptr (또는 0, pre C++ 11)으로 설정되지 않기 때문입니다. 고려 :

std::vector<Point> unique_points; 
std::vector<Point*> used_points; 

// create all needed points *once* in unique_points 
// insert pointers to the points in unique_points into used_points 
  • : std::shared_ptr

  • 독특한 인스턴스에 대한 별도의 std::vector을 가지고

    1. 사용 :

      int *foo = new int; 
      // foo should be non-nullptr now 
      int *bar = foo; 
      // bar should be non-nullptr now 
      delete foo; 
      // both foo and bar are still non-nullptr. 
      

      사용자의 특정 문제를 해결하는 방법은 세 가지가 있습니다 그냥 복사 해.

  • +0

    @Skaktal 아래의 대답은 삭제 한 후에 항목을 NULL로 설정하면 안되는 이유는 무엇입니까? 당신이 위에서 준 옵션에서 나는 그것을 보지 못했기 때문에 그렇게해야했습니다. – user1240679

    +0

    @ user1240679 같은 개체에 대한 다른 포인터를 null로 설정하지 않습니다. –

    +0

    아하! 그래서, 그러한 할당은'vector * pointsList','pointsList = sharedPointsList' 유효합니다. 여기서'sharedPointsList'는'vector *'입니다. 또한 위의 경우 포인터가 가리키는 데이터의 복사본을 만드는 가장 좋은 방법은 무엇입니까? – user1240679

    7

    스마트 포인터를 사용하십시오. 프로그램 소스에 delete이 포함되어 있고 스마트 포인터 삭제 프로그램에 있지 않으면 프로그램이 손상됩니다. (도대체 왜 std::default_deleter 대신에 그 일을 할 것입니까?).

    "Best Smart Pointer Award 2014"의 우승자는 std::unique_ptr이며 포인터를 복사해야하는 경우 std::shared_ptr에 대한 영예로운 언급이 있습니다.

    제로 규칙은 자신을 관리하기 위해 항상 일반적인 리소스 관리 클래스를 사용해야하므로 소멸자/etc를 직접 구현할 필요가 없다는 것을 의미합니다.

    +1

    'std :: shared_ptr'과 ['' std :: weak_ptr'] (http://en.cppreference.com/w/cpp/memory/weak_ptr), OP가 설명한 유스 케이스를 관리하는 데 매우 적합합니다. –

    +1

    'weak_ptr'이 나에게 도움이 될만한 것은 없습니다. 복사를 가능하게하기 위해 refcounting에 돈을 지불한다면, 대다수의 시간 동안'shared_ptr '을 보유 할 수 있습니다. – Puppy

    0

    일반적인 대답은 동적 메모리를 사용할 때 정리를위한 계획을 세우는 것입니다.

    하나의 계획은 다양한 형태의 표준 라이브러리 템플릿 포인터 관리자를 사용하는 것입니다 (위에서 설명한대로). 그러나 이것을 수행하는 다른 방법이 있습니다.

    "최상의"계획은 현재 진행중인 응용 프로그램의 유형에 따라 다릅니다. 예를 들어, 일부 그래프 구조를 사용하는 경우 해당 메소드가 다른 유형의 구조와 함께 작동 할 때 참조 계산이 작동하지 않을 수 있습니다.

    예를 들어, 당신은 당신이있을 때 참조 카운팅을 수행하려고 할 경우

    B 2 C 1 D 1 E 2

    이를 파괴 다음 참조 횟수를 제공

    A points to B. 
    B points to C and D 
    C and D points to E 
    E points to B 
    

    링크 A-> B는 이러한 참조 카운트를 제공합니다.

    B 1 C 1 D 1 E 2

    구조에 대한 참조가 없으므로 절대로 삭제되지 않습니다.

    상황에 가장 적합한 계획을 선택하십시오.