문제

한 모듈에서 무언가를 새로 만들고 다른 모듈에서 삭제하면 VC++에서 문제가 발생할 수 있다는 것을 알고 있습니다.다양한 런타임에 문제가 있습니다.정적으로 링크된 런타임 및/또는 동적으로 링크된 버전 관리 불일치와 모듈을 혼합하면 올바르게 기억할 경우 문제가 발생할 수 있습니다.

그러나 VC++ 2008의 std::tr1::shared_ptr을 모듈 전체에 사용해도 안전합니까?

shared_ptr이 무엇인지 아는 런타임 버전이 하나뿐이므로 정적 링크가 유일한 위험입니다(현재로서는...).나는 Boost의 shared_ptr 버전이 이와 같이 사용하기에 안전하다는 것을 읽었다고 생각했지만 Redmond의 버전을 사용하고 있습니다 ...

할당 모듈에서 객체를 해제하기 위한 특별한 호출을 피하려고 합니다.(또는 클래스 자체에서 "delete this"와 같은 것).이 모든 것이 약간 이상해 보인다면 단위 테스트에 이것을 사용하고 있습니다.기존 C++ 코드를 단위 테스트해 본 적이 있다면 어떻게 해야 하는지 이해할 수 있습니다. 창의적인 당신은 때때로 있어야합니다.내 메모리는 EXE에 의해 할당되지만 궁극적으로 DLL에서 해제됩니다(참조 계산이 내가 생각하는 대로 작동하는 경우).

도움이 되었습니까?

해결책

메모리를 해방시키는 것은 모든 것이 똑같은 한 안전합니다. 메모리 관리 문맥. 가장 일반적인 문제 (다른 C ++ runtimes)를 식별했습니다. 별도의 힙을 갖는 것은 당신이 뛸 수있는 또 다른 덜 공통 문제입니다.

당신이 언급하지 않았지만 공유 포인터로 외부화 할 수있는 또 다른 문제는 DLL에 객체의 코드가 존재하고 DLL에 의해 생성 될 때, DLL 외부의 다른 객체는 (공유를 통해 참조로 끝납니다. 바늘). DLL이 언로드 된 후 해당 객체가 파괴 된 경우 (예 : 모듈 레벨 정적 인 경우 또는 DLL에 명시 적으로 언로드 된 경우 FreeLibrary(), 공유 물체의 소멸자가 충돌합니다.

DLL 기반, 느슨하게 결합 된 플러그인을 작성하려고하면 물릴 수 있습니다. Com이 DLLS가 언제 ~할 수 있다 COM 서버가 요구하지 않고 언로드하십시오.

다른 팁

당신은 얼마나 놀라 울 정도로 놀랍도록보기 시작했습니다 shared_ptr 이다 :)

DLL 경계를 가로 질러 안전하다는 것은 정확히 무엇입니다 shared_ptr 물론 (물론)가되도록 설계되었습니다.

다른 사람들이 말한 것과는 달리, 당신은 shared_ptr, 기본값은 이미 같은 것입니다

template <typename T>
struct default_deleter {
    void operator()( T * t ) { delete t; }
};

그리고

shared_ptr<Foo> foo( new Bar );

동일합니다

shared_ptr<Foo> foo( new Bar, default_deleter<Bar>() );

(예 : shared_ptr DELETER없이).

Deleter에서 수행 된 유형 삭제로 인해 delete 그것은 윌이라고합니다 언제나 DLL에서 나온 사람이 되십시오 인스턴스화 그만큼 shared_ptr, 마지막으로 DLL에서 절대로 shared_ptr 범위를 벗어납니다 (즉 shared_ptr Deleter를 호출하면 원본이 넣은 함수에 대한 포인터를 통해 호출합니다. shared_ptr).

이것을 비교하십시오 auto_ptr, 그것은 delete (인라인) 소멸자로 직접 운영자가 delete DLL의 파괴 그만큼 auto_ptr 알몸 포인터를 삭제하는 것과 동일한 문제를 만듭니다.

동일한 기술로 항상 개최되는 다형성 클래스 shared_ptrDELETER는 마지막으로도 오른쪽 소멸자를 호출하기 때문에 가상 소멸자가 필요하지 않습니다. shared_ptr 범위를 벗어나는 것은 기본 클래스에 인스턴스화 된 것 중 하나입니다.

관심이있는 경우 Deleter 인수를 취하는 Shared_PTR 생성자의 형태를 사용하십시오. Deleter는 삭제가 올바른 컨텍스트에서 발생하도록 객체를 할당 한 모듈로 다시 호출 할 수 있습니다.

Boost의 문서화는 그것이 TR1과 100% 호환되었다고 주장하므로 이것에 대해 오해의 소지가 없기를 바랍니다.

http://www.boost.org/doc/libs/1_37_0/libs/smart_ptr/shared_ptr.htm#constructors

수업을 사용하는 것이 안전하다고 생각합니다. std 모듈을 가로 질러.

즉, 모듈이 정확히 동일한 런타임 라이브러리와 정확히 동일한 컴파일러 스위치 및 옵션을 사용하는 경우 안전해야합니다.

각 모듈은 모든 글로벌의 자체 인스턴스를 얻을 수 있으므로 정적 런타임 라이브러리를 사용하지 마십시오.

일반적인 주제에 관해 제가 본 최고의 조언은 메모리가 할당된 것과 동일한 컨텍스트에서 메모리 할당을 해제해야 한다는 것입니다.그러나 이는 애플리케이션 코드가 해제해야 하는 포인터를 라이브러리가 다시 전달하는 것을 배제하지 않으므로 동일한 일반적인 상황이므로 이런 방식으로 shared_ptr을 전달하는 것이 아마도 안전할 것이라고 말하고 싶습니다.

시스템의 의미가 포인터가 실제로 (소유권 측면에서) exe에서 dll로 전송된다는 것을 의미한다면 auto_ptr이 더 나은 솔루션일 수 있습니다.그러나 포인터가 실제로 공유된다면 shared_ptr이 아마도 가장 좋은 솔루션일 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top