2013-02-02 3 views
1

C++에서 벡터에 객체를 추가하고 해당 객체에 대한 포인터를 삭제하면 벡터 내의 객체도 삭제됩니까? 예를 들어벡터에 추가 한 후 포인터 할당 삭제

,

int i = 0; 
std::vector<A> aVect; 
while(i++ < 10) 
{  
    A *ptrToA = new A(); 
    aVect.push_back(*ptrToA); 
    delete ptrToA; 
} 

는 여전히 전화를 유효한 것 :

aVect.at(2); 

의지를 단지 벡터에 추가 된 객체를 파괴, 또는 것 "삭제"에 대한 호출 포인터의 객체를 할당 해제 하시겠습니까?

+0

그것은 aVect''의 내용을 파괴하지 않지만'A'가 제대로 자원을 스스로 관리 할 내부 동적 할당을 사용 않는 경우는 *'aVect' 내에서 일부'A' * 콘텐츠를 파괴 할 수있다 . 특히, 가상 파괴, 복사 건설 및 복사 할당. 자세한 내용은 [The Rule of Three] (http://en.wikipedia.org/wiki/Rule_of_three_ (C % 2B % 2B_programming))를 참조하십시오. – WhozCraig

답변

1

예, 포인터를 삭제할 수 있습니다. 다른 사람이 포인터를 역 참조했다는 사실을 알고 있으므로 값으로 벡터에 복사됩니다.

그냥/완전히 삭제 같은 벡터로 구성하고 새로운 피하기 위해 더 효율적인 것

: C++ 11에서

int i = 0; 
while(i++ < 10) 
{  
    std::vector<A> aVect; 
    aVect.push_back(A()); 
} 

사본이 만들어되지 않습니다 -와 push_back의를 rvalue 버전이됩니다 used - A가 벡터의 슬롯에 생성됩니다.

매번 새로운 벡터를 만들고 싶지 않을 수도 있습니다.

std::vector<A> aVect; 
int i = 0; 
while(i++ < 10) 
{  
    aVect.push_back(A()); 
} 
+2

루프를 사용해야하는 이유는 무엇입니까? 'std :: vector aVect (10, A()); ' – chris

+0

@chris 좋은 지적. 나는 누군가가 진짜로 그것을 할 것이라고 생각하지 않았다고 생각한다. 나는 실제 코드에 다른 ctor 인수가있는 다른 A가 삽입 될 것으로 기대합니다. 나는 하나의 기본 생성 된 벡터를 생성 할 수 있고 A와 함께 나중에 그들을 조작합니다. – emsr

+0

답변 해 주셔서 감사합니다. while 루프는 유용하다. 내가 추측 할 때마다 다른 매개 변수를 가진 객체를 추가하고 싶다. a.V.push_back (A (i)); 또는 그런 것. 그러나 이것은 메모리 관리에 대해 걱정할 필요가 없기 때문에 시간을 절약 해줍니다. – mma1480

0

여기서 개체의 복사본을 벡터에 푸시하면이 사본이 삭제되지 않습니다. 벡터에서

int i = 0; 
while(i++ < 10) 
{  
    A *ptrToA = new A(); 
    std::vector<*A> aVect; 
    aVect.push_back(ptrToA); 
    delete ptrToA; 
} 

그럼 당신은 밀고 포인터를하고 ptrToA을 삭제하면 당신은 또한 요소가 벡터에 포인터가 가리키는 삭제 :

당신이 쓰는 그러나합니다.

0

유형 A : std::vector<A>의 객체 벡터를 만들었습니다. 즉, 새 객체를 삽입하면이 새 객체의 사본이 생성되어 벡터에 저장됩니다.

그렇습니다. 새 오브젝트가 삭제 된 후에도이 요소에 액세스하는 것이 안전하고 유효합니다. 원본 개체를 삭제해도 벡터에 저장된 복사본에는 아무런 영향을 미치지 않습니다.

이러한 종류의 벡터 (자동 저장 기간이있는 객체를 보유하는 벡터)의 장점은 벡터가 파괴되면 이러한 객체가 저장된 메모리가 자동으로 정리된다는 것입니다. 그래서 코드에 메모리 누수가 생길 확률이 적어지고 자신 만의 추한 메모리 관리를 할 필요가 없기 때문에 작업량이 줄어들 것입니다.

0

아니요. . std::vector<A>은 포인터가 아닌 오브젝트의 인스턴스를 저장합니다. 실제로 A를 벡터로 밀어 넣는 동안 포인터를 역 참조합니다.

이것은 (copy constructor을 통해 빌드 된) 객체의 사본이 벡터 안에 저장되게합니다. 객체를 푸시 한 후 A 클래스의 인스턴스가 2 개 있습니다. 하나의 인스턴스가 heap (new operator 통해)에 할당됩니다. 다른 인스턴스는 stack에 있으며 여기에서 aVect이 할당됩니다. 한편

, 당신의 벡터 ( std::vector<*A>) 포인터를 저장한다면, ptrToA을 삭제 한 후, 포인터는 이미 출시 된 메모리 위치 ( dangling pointer)에 벡터 포인트를 내부에 저장됩니다. 해당 포인터에 액세스하려고하면 오류가 발생합니다 (아마도 segfault).

1

벡터가 *ptrToA 사본을 보유하고 있으므로 aVect.at(2)을 호출해도 유효합니다. aVect.push_back(*ptrToA)을 호출하면 할당 연산자를 사용하여 A을 설정합니다.

관련 문제