2014-04-01 3 views
1

배경

I는 networkprotocol위한 드라이버를 작성하고이 packagestd::array<buffer_ptr,2>되는 함수 write(std::shared_ptr<package> package) 가질하고 (0 => 헤더, 1 => 본체)와 어레이. 편의상 나는 write(buffer_ptr body) 함수를 작성하여 헤더를 자동 생성하고 write의 첫 번째 양식을 호출한다. 이렇게하려면 std::make_shared을 보내고 make_shared 호출에서 std::array을 초기화하는 데 문제가 있습니다.초기화 표준 : make_shared

내가 재판을 어떤 코드

typedef std::shared_ptr<std::vector<uint8_t>> buffer_ptr; 
typedef std::array<buffer_ptr, 2> package_t; 
typedef std::shared_ptr<package_t> package_ptr; 

void connection::write(package_ptr package) { 
    ... //do stuff 
} 

void connection::write(buffer_ptr body) { 
    buffer_ptr header = buildHeader(body); 
    write(std::make_shared<package_t>(???)) //here I want to initialize the array with {header,body} 
} 

???

{header, body} 
{{header, body}} 
std::initializer_list<buffer_ptr>{header, body} 

질문 (이러한 오류를 컴파일러 LED) :

이 일을 할 수있는 솔루션이 아니면 내가 좋아하는 뭔가를 작성해야 할 :

package_ptr 패키지를 = 새 패키지 {header, body}; 쓰기 (패키지);

1.b) package_ptr(new package)에 의존해야 효율성이 떨어지나요? Cppreference

  • 이다 (I 메모리 요청을 저장하는 포인터와 한 덩어리의 인스턴스에 대한 공유 메모리 할당을 기억하는 것은) 읽

    또한

    , F (shared_ptr의 (새 INT (42)) , g()) g가 예외를 throw하면 메모리 누수가 발생할 수 있습니다. make_shared가 인 경우이 문제는 존재하지 않습니다.

    왜 메모리가 유출 될 수

    (int(42)라고 g 전에 구축 할 수 있으며, shared_ptr 전에 호출 할 g라고합니다)? 그리고 1. 대체 코드가 그러한 누출 가능성으로부터 고통을 겪을까요? 먼저

  • +2

    '쓰기 (표준 : make_shared (package_t {헤더, 바디})); ' – Cubbi

    +0

    @Cubbi Nice! 마이크로 소프트 컴파일러는 그것을 좋아하지 않았다 : ( –

    +0

    @Cubbi :'make_shared'가 던져 질 때 (예 : 메모리 부족)? 이미 빌드 된'package_t'가 유출 되었습니까? – ted

    답변

    1

    :

    array 명시 적으로 생성자를 선언하지 않습니다. 특히 이니셜 라이저 목록을 사용하는 생성자가 없습니다.

    나는 깨끗한 방법은 코드에서 명시 적 new을 피하고 표준 기능으로 떠날 생각 :

    package_t p = {header, body}; 
    write(std::make_shared<package_t>(p)); 
    
    newstd::shared_ptr이 있다면 코드는 더 나은 모습 것

    :

    package_t p = {header, body}; 
    write(p); 
    

    둘째 Cppreference.com에 읽

    또한 예외가 throw되면 f (shared_ptr (new int (42)), g()) 은 메모리 누수로 이어질 수 있습니다.make_shared가 사용되는 경우이 문제는 이 아닙니다.

    표준은 함수 인수를 평가하는 순서를 지정하지 않으며 표현식은 동일한 결과를 산출하는 한 임의의 순서로 평가할 수 있습니다.

    f(shared_ptr(new int(42)), g()) 
    

    new int(42)에서

    shared_ptr()하지만 g()을 선행해야하고 g가 발생하는 경우이 누수가 발생할 수 있습니다.

    f(make_shared<int>(42), g()) 
    

    에서

    할당은 make_shared 안에 일어난다. make_shared 전에 g이 호출되고 throw되면 메모리가 할당되지 않습니다. make_sharedg 전에 호출되고 g가 발생되면, shared_ptr 개체가 이미 생성 된 것이며이 파괴 때문에 RAII의 보장 인 경우

    +0

    'shared_pointer'는 비동기 쓰기를 통과하고 쓰기가 콜백을 호출 한 후 포인터가 헤더/본문을 해제하는 데 사용되므로 남아 있어야합니다. – ted

    관련 문제