هل من الآمن استخدام المحكمة الخاصة بلبنان (TR1) shared_ptr بين وحدات (exes و dlls)

StackOverflow https://stackoverflow.com/questions/345003

سؤال

وأنا أعلم أن الجديد-ing شيء في وحدة واحدة وحذف جي في آخر كثير من الأحيان يمكن أن يسبب مشاكل في VC++.مشاكل مع مختلف أوقات التشغيل.خلط وحدات مع staticly ربط أوقات التشغيل و/أو مرتبطة بشكل حيوي الإصدارات التطابق على حد سواء يمكن أن المسمار الأشياء إذا كنت أتذكر بشكل صحيح.

ولكن هل من الآمن استخدام VC++ 2008 std::tr1::shared_ptr عبر وحدات?

لأنه ليس هناك نسخة واحدة فقط من وقت التشغيل الذي يعرف حتى ما shared_ptr هو ثابت ربط هو الخطر الوحيد (حتى الآن).ظننت أنني قرأت أن دفعة نسخة shared_ptr كان من الآمن استخدام مثل هذا, ولكن أنا باستخدام ريدموند الإصدار...

أنا في محاولة لتجنب الاضطرار خاصة إلى الكائنات في تخصيص وحدة.(أو شيء من هذا القبيل "حذف" في الصف نفسه).إذا كان كل هذا يبدو قليلا hacky, أنا باستخدام هذا اختبار وحدة.إذا كنت قد حاولت من أي وقت مضى إلى وحدة اختبار القائمة رمز C++ هل يمكن أن نفهم كيف الإبداعية عليك أن تكون في بعض الأحيان.ذاكرتي التي خصصتها EXE ولكن في نهاية المطاف سوف يكون الافراج في DLL (إذا كان المرجع عد يعمل بالطريقة التي أعتقد أنها لا).

هل كانت مفيدة؟

المحلول

تحرير الذاكرة بأمان طالما أنه جاء من نفس إدارة الذاكرة السياق.كنت قد حددت المشكلة الأكثر شيوعا (مختلف C++ أوقات التشغيل);وجود أكوام منفصلة أخرى أقل شيوعا المشكلة التي يمكن أن تصل إلى.

مسألة أخرى لم تذكر ، ولكن الذي يمكن أن يكون exascerbated المشتركة المؤشرات ، هو عندما كائن هو رمز موجود في DLL و يتم إنشاؤه من قبل DLL, ولكن كائن آخر خارج DLL ينتهي مع إشارة إلى أنه (طريق مشترك المؤشر).إذا كان هذا الكائن هو تدميرها بعد DLL يتم تفريغ (على سبيل المثال ، إذا كان مستوى الوحدة النمطية الساكنة ، أو إذا كان DLL صراحة تفريغها من قبل FreeLibrary(), المشتركة الكائن المدمر سوف تحطم الطائرة.

هذا يمكن لدغة لك إذا كنت تحاول كتابة DLL المستندة إلى جانب فضفاضة الإضافات.وهو أيضا السبب الذي COM يتيح DLLs تقرر عند يمكن يتم تفريغ, بدلا من السماح ملقمات COM الطلب يفرغ منها.

نصائح أخرى

لقد بدأت أرى كيف مذهلة بشكل لا يصدق shared_ptr هو :)

كونها آمنة عبر DLL الحدود هو بالضبط ما shared_ptr صمم ليكون (من بين أمور أخرى, بالطبع).

على عكس ما قاله الآخرون, حتى أنك لا تحتاج إلى تمرير العرف deleter عند بناء 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>() );

(ie.لا يوجد شيء مثل shared_ptr دون deleter).

بسبب نوع المحو التي أجريت على deleter ، delete يسمى هذا سوف دائما تكون واحدة من DLL إنشاء مثيل على shared_ptr, أبدا واحد من DLL حيث الماضي shared_ptr يخرج من نطاق (ie.على shared_ptr الاحتجاج deleter سوف يطلق عليه من خلال مؤشر على وظيفة وضعت هناك من قبل الأصلي shared_ptr).

قارن هذا إلى auto_ptr, الذي يضمن delete المشغل مباشرة في (مضمنة) المدمر ، مما يعني أن delete DLL يدمر على auto_ptr يستخدم خلق نفس المشاكل حذف عارية المؤشر.

من قبل نفس تقنية متعددة الأشكال الطبقات التي هي دائما في shared_ptrs لا تحتاج حتى الظاهري المدمر ، لأن deleter دائما ندعو حق المدمر ، حتى حين آخر shared_ptr إلى الخروج من نطاق واحد مثيل لهذه الفئة الأساسية.

إذا كنت قلقا ، استخدام شكل shared_ptr منشئ أن يأخذ deleter الحجة.على deleter يمكن أن ندعو مرة أخرى إلى الوحدة النمطية التي خصصت الكائن بحيث يتم حذف يحدث في السياق الصحيح.

دفعة وثائق يدعي أنه هو 100 ٪ متوافق مع TR1, لذلك نأمل أن لا يوجد شيء مضللة حول هذا:

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

أعتقد أنها آمنة كما أن استخدام أي من الفئات في std عبر وحدات.

وهذا هو:يجب أن تكون آمنة إذا كانت وحدات استخدام نفس مكتبة وقت تشغيل و بالضبط نفس رموز تبديل برنامج التحويل البرمجي و الخيارات.

أبدا استخدام ثابت مكتبة وقت التشغيل ، حيث أن كل وحدة سوف تحصل على الدرجة الخاصة من جميع globals داخلها.

أفضل نصيحة رأيت في الموضوع هو أن الذاكرة يجب أن يكون deallocated في نفس السياق انه المخصصة.هذا لا يمنع مكتبة يمر الظهر مؤشر على أن تطبيق قانون يفترض مجانا ومع ذلك, لذلك أنا أقول ربما كنت آمنة اجتياز shared_ptr في هذه الطريقة ، كما إنها نفس الحالة العامة.

إذا دلالات النظام الخاص بك يعني أن المؤشر هو في الواقع نقل (في ملكية الشعور) من exe dll الخاص بك ، ثم auto_ptr قد يكون أفضل حل.ومع ذلك ، إذا كان المؤشر الخاص بك هو حقا المشتركة ، ثم shared_ptr هو على الارجح أفضل حل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top