2011-08-18 5 views
0

previous question의 속편으로 다음 코드에서 내가 뭘 잘못하고 있는지 물어보고 싶습니다.새로운 사용/삭제의 올바른 사용

코드는 예를

void myclass1::myfun() 
{ 
myclass2* newVar = new myclass2(); 
/* other code and stuff */ 
myvector.push_back(newVar); // myvector is a member of myclass1 and is a std::vector<myclass2*> 
delete newVar; 
} 

에 대한,하지만 난 그것을 실행할 때 나는 delete 줄을 주석으로하지 않는 한, myvector는 빈 반환합니다.

내가 뭘 잘못하고 있니?

답변

2

이미 말했듯이 이미 메모리를 해제하면 메모리에 액세스하거나 메모리를 변경할 수 없습니다. 소멸자 (또는 추가 기능)에서 개체를 삭제해야합니다. 여기에 그렇게 할 것 단편이다 :

// this function adds the object 
`void MyClass1::AddFun() 
{ 
    myClass2* Ptr = new myClass2(); // create new object via new-operator 
    myvector.push_back(Ptr); 
} 

// this function clears the entire vector 
void MyClass1::ClearAllContent() 
{ 
    while (myvector.empty() == false) 
    { 
    delete myvector[myvectory.size() - 1]; // free the last object in your vector 
    myvector.pop_back();     // pop_back reomves the "empty"-pointer 
    } 
} 
3

개체를 완전히 사용한 후에 만 ​​개체를 ​​삭제하고 싶습니다. 삭제 한 후에는 다시 참조하지 마십시오.

일반적인 경우 벡터에 개체에 대한 포인터가 아니라 개체 자체를 넣기 만하면됩니다. 이렇게하면 개체를 벡터에 추가 할 때 개체의 복사본이 만들어지고 벡터에서 개체를 지울 때 개체가 자동으로 삭제되거나 벡터 자체가 파괴됩니다.

+0

오, 맞았습니다. 감사. 삭제 선을 제거하면 벡터가 삭제되면 어떻게됩니까? 포인터 만 삭제됩니까? 감사합니다 – Federico

+0

@Federico : 맞습니다. pointee가 아닌 포인터 만 삭제됩니다. 그 포인터를 "스마트 포인터"로 감싸는 것이 아니라면, 당신을 위해'delete'를 처리해야합니다. – ereOn

+0

@ereOn : understand. 문제는 내가 벡터를 포인터 중 하나의 벡터에서 변경할 수 없다는 것입니다 (변경 하기엔 너무 많은 코드, 너무 많거나 너무 커서 모든 개체가 .push_back에 다시 할당되면 응용 프로그램이 느려질 수 있습니다.)). 벡터를 삭제할 때 어떻게 지적자를 삭제할 수 있습니까? 이 "스마트 포인터"는 무엇입니까? 그 (것)들은 buit-in이고 또는 나는 그 (것)들을 정의해야 하는가? 다시 한번 감사합니다. – Federico

1

C++은 C# 또는 Java 등이 아닙니다. 당신은 아마도하지 말아야 할 원시 포인터를 사용하고 있습니다. 그냥 할당 된 개체를 삭제하면 사라지고 더 이상 사용할 수 없습니다. 함수의 범위를 벗어나 지속되는 것으로 보이는 벡터에 포인터를 저장하면 오류가 발생합니다.

1

당신은 힙에 myclass2의 인스턴스를 생성 한 다음 벡터로의 포인터를 넣어. delete newVar;을 수행하면 방금 작성한 인스턴스가 파기됩니다. 그러나 당신의 벡터는 여전히 객체가 있던 곳의 포인터를 가지고 있으며 그 포인터는 더 이상 유효하지 않습니다.

더 이상 힙에 개체가 필요하지 않은 경우 delete으로 전화해야합니다.

  1. 개체를 삭제하지 마십시오 다음과 같이

    옵션은 다음. 즉, 프로그램의 다른 지점에서 모든 항목을 삭제해야 할 때 삭제해야합니다. 좌표를 정하기가 어려울 수 있으므로 스마트 포인터를 사용해야합니다. Boost 라이브러리 또는 표준 라이브러리에서 shared_ptr을 찾을 수 있습니다 (C++ 0x로 컴파일하는 경우). 다음은 C + +0에서 사용 줄 방법은 다음과 같습니다

    #include <vector> 
    #include <memory> 
    #include <algorithm> 
    #include <iostream> 
    
    int main(int argc, const char* argv[]) { 
        typedef std::vector<std::shared_ptr<int>> Vector; 
    
        Vector v = { 
        Vector::value_type(new int(2)), 
        Vector::value_type(new int(5)) 
        }; 
    
        std::for_each(v.begin(), v.end(), [](Vector::value_type x) { 
        std::cout << *x << std::endl; 
        }); 
    
        return 0; 
    } 
    
  2. 는 힙에 객체를 할당하지 마십시오. 대신 myclass에 대한 포인터 대신 myclass의 인스턴스로 벡터를 채 웁니다. 이제 벡터는 std::vector<myclass2>이됩니다.

선택 사항이있는 경우 두 번째 옵션이 좋습니다. myclass2의 인스턴스는 벡터가 파괴 될 때마다 파괴되어 해당 트랙을 관리하는 번거 로움을 덜어줍니다.

2

delete를 호출하면 newVar의 소멸자가 호출되고 new에 의해 할당 된 메모리가 힙으로 다시 반환됩니다.

이 시점에서 삭제를 호출하면 안됩니다.myclass1의 소멸자 또는 다른 멤버 함수에서 수행하십시오.

은 다음과 같습니다 : 벡터 값 또는 boost :: shared_ptr <과 같은 스마트 포인터로 저장하십시오. 스마트 포인터는 귀하의 경우입니다. myvector의 요소를 삭제하는 것에 대해 걱정할 필요도 없습니다. 왜냐하면 myvector가 소멸 될 때 해당 요소가 올바르게 소멸 될 것이기 때문입니다. 예제 코드는 다음과 같습니다.

void myclass1::myfun() 
{ 
    myvector.push_back(boost::shared_ptr<myclass2>(new myclass2())); 
}