2014-12-22 2 views
1

중첩 된 boost :: shared_ptr이 있는데, 다른 하나에 할당되고 범위를 벗어날 때 가끔 파괴됩니다. 나는 포인터를 임시로 복사하지 않으면 use_count가 업데이트되지 않는다는 것을 알아 냈습니다. 코드는 자명하다. 첫 번째 for 루프에서 use_count는 업데이트되지 않지만 다른 루프에서는 업데이트됩니다.중첩 된 boost :: shared_ptr use_count가 업데이트되지 않음

#include <vector> 
#include <boost/shared_ptr.hpp> 
#include <iostream> 
using namespace std; 



int main(int argc, char const *argv[]) 
{ 
    typedef int T; 
    typedef std::vector<T> content_1d_t; 
    typedef boost::shared_ptr<content_1d_t> storage_1d_t; 
    typedef std::vector<storage_1d_t> content_2d_t; 
    typedef boost::shared_ptr<content_2d_t> storage_2d_t; 

    int dim1 = 10; 
    int dim2 = 1; 
    content_2d_t* content_1 = new content_2d_t(); 
    content_1->reserve(dim2); 
    storage_2d_t storage_1(content_1); 

    for (int i = 0; i < dim2; ++i) 
    { 
    storage_1->push_back(storage_1d_t(new content_1d_t(dim1))); 
    } 

    //content_2d_t* content_2 = new content_2d_t(dim2); 
    storage_2d_t storage_2 = storage_1; 

    for (int i = 0; i < dim2; ++i) 
    { 
    cout<< "use count before : "<< storage_1->operator[](i).use_count()<<endl; 
    storage_2->operator[](i) = storage_1->operator[](i); 
    cout<< "use count after: "<< storage_1->operator[](i).use_count()<<endl; 
    } 

    for (int i = 0; i < dim2; ++i) 
    { 
    cout<< "use count before : "<< storage_1->operator[](i).use_count()<<endl; 
    storage_1d_t ref = storage_1->operator[](i); 
    storage_2->operator[](i) = ref; 
    cout<< "use count after: "<< storage_1->operator[](i).use_count()<<endl; 
    } 


    /* code */ 
    return 0; 
} 

출력

사용 횟수 전에 1

사용 횟수 후 1

사용 횟수 전에 1

사용 횟수 후 2

답변

3

storage_2d_t storage_2 = storage_1;이 분명하기 때문에 요소를 직접에 직접 할당해도 사용 횟수가 증가하지 않습니다.

나는 임시 복사본 (ref)을 보유하고있는 시간 동안 사용 횟수를 인쇄합니다. 그것은 명시 적으로 만들기, 당신은 실제로 그것을 볼 수 있습니다 - 예상대로 - (가) "다음은"카운트가 아닌 실제로 이상 :

for (int i = 0; i < dim2; ++i) { 
    cout << "use count before : " << (*storage_1)[i].use_count() << endl; 
    { 
     storage_1d_t ref = (*storage_1)[i]; 
     (*storage_2)[i] = ref; 
     cout << "use count during: " << (*storage_1)[i].use_count() << endl; 
    } 
    cout << "use count after: " << (*storage_1)[i].use_count() << endl; 
} 

지금

use count before : 1 
use count during: 2 
use count after: 1 

이 그것을 Live On Coliru


보기 인쇄

브레인 웨이브storage_1을에 깊이 복제 했습니까?? 바깥 storage_2d_t가 이고 또한 공유 포인터이기 때문에 참조로 동일한 벡터를 참조하면 혼란스러워 보입니다.

storage_2d_t storage_2 = boost::make_shared<content_2d_t>(*storage_1); 
// or 
storage_2d_t storage_2 = boost::make_shared<content_2d_t>(storage_1->begin(), storage_1->end()); 
+0

나는 공유 포인터를 깊이 복제하고 싶지 않습니다. shared_pointer의 shallow 복사 생성자가 호출 될 때 use_count를 증가시키는 것은 하나뿐입니다. 그래서 당신은 임시 복사본의 일생 동안 트릭이 use_count를 증가 시켰다고 제주의를 기울였습니다. 그렇다면 왜 내가 (* storage_2) [i] = (* storage_1) [i]를 할당 할 때 그것을 늘릴 수 없습니까? 이것은 공유 포인터를 할당하고 있으며 (* storage_2) [i]의 수명 동안 사용 횟수를 증가시킬 공유 포인터의 복사 생성자를 호출해야합니다 ... – mustafabar

+0

@mustafabar 첫 문장의 요점을 완전히 놓쳤습니까? 당신은 ** 복사하지 않습니다. ** 자체에 ** 요소를 할당하고 있습니다. 'storage_1'과'storage_2'는 같은 컨테이너를 가리 킵니다 ***. – sehe

+1

나는 당신의 요점을 놓치지 않았습니다. 스마트 포인터 복사 생성자는 본질적으로 주소의 복사본이지 뾰족한 데이터의 딥 복사본이 아닙니다. 이렇게하면 새 메모리를 할당하지 않고이 메모리 조각에 대한 참조 횟수가 늘어납니다. – mustafabar

관련 문제