سؤال

إذا قمت باستخدام new الكلمة الرئيسية في مكتبتي (التي تم إنشاؤها بشكل مختلف عن تطبيقي الرئيسي)، عندما أحذفها في تطبيقي الرئيسي باستخدام delete, ، هل هناك احتمال أن أتعرض لعطل/خطأ؟

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

المحلول

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

نصائح أخرى

هذا يعتمد.إذا كنت تتحدث عن مكتبة ثابتة، فمن المحتمل أن يكون الأمر على ما يرام - سيتم تشغيل التعليمات البرمجية في نفس سياق البرنامج الرئيسي، باستخدام نفس مكتبة وقت تشغيل C++.هذا يعني ذاك new و delete سوف تستخدم نفس الكومة.

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

الاتصال delete (في البرنامج الرئيسي) على المؤشر المخصص بواسطة DLL (أو العكس) سيؤدي إلى (في أحسن الأحوال) تعطل فوري أو (في أسوأ الأحوال) تلف الذاكرة الذي سيستغرق بعض الوقت لتعقبه.

لديك خياران.الأول هو استخدام نمط "طريقة المصنع" لإنشاء هذه الكائنات وحذفها:

Foo *CreateFoo();
void DeleteFoo(Foo *p);

ينبغي لهذه لا يتم تنفيذها في ملف الرأس.

وبدلاً من ذلك، يمكنك تحديد أ Destroy الطريقة على الكائن:

class Foo
{
    ~Foo();

public:
    virtual void Destroy();
};

...مرة أخرى، لا تقم بتنفيذ هذا في ملف الرأس.يمكنك تنفيذه على النحو التالي:

void Foo::Destroy()
{
    delete this;
    // don't do anything that accesses this object past this point.
}

لاحظ أن أداة التدمير الخاصة بـ Foo خاصة، لذا يتعين عليك الاتصال بها Foo::Destroy.

يقوم Microsoft COM بشيء مشابه، حيث يقوم بتعريف ملف Release الطريقة التي تحذف الكائن عندما ينخفض ​​عدد مرجعه إلى الصفر.

نعم، أنتم أيضا. وهناك حل بسيط هو توفير انشاء وحذف وظائف في المكتبة التي يمكن استدعاؤها من التطبيق الرئيسي. وإنشاء وظيفة أداء جديدة وإرجاع المؤشر، الذي تم تمريره في وقت لاحق إلى وظيفة حذف للحذف.

وانها مشكلة التي رأيتها فقط على ويندوز.

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

وأنا يجب أن أقول، هذه المشكلة يخلق ويندوز مع مختلف دلس C وقت التشغيل هو حقا مزعج وغير طبيعية لمبرمج C. نظرة على مكتبة C. لديها وظائف مثل strdup أن malloc السلسلة، ونتوقع مبرمج للاتصال مجانا () على ذلك. ولكن أن تفعل الشيء نفسه في مكتبتك الخاصة على ويندوز وليس علينا سوى الانتظار لانفجار. سوف تضطر إلى الانتظار، أيضا، لأن ذلك لن يحدث خلال تطوير ولكن فقط بعد أن كنت قد أعطيت DLL المترجمة إلى بعض النسغ الفقراء الآخرين.

وقد غطت

قديم الشيء الجديد هذا من قبل . وقال انه يعطي أيضا قائمة من الحلول الرئيسية مايكروسوفت.

وأنت على حق تماما أن هناك مشكلة هناك، ولكن بالنسبة لمعظم الحالات لا يوجد حل حتى أبسط من إجابات أخرى (حتى الآن) والمقترح. يمكنك الاستمرار في استخدام جديدة وحذف بحرية - كل ما عليك القيام به هو الزائد جديد وحذف لكل فئة في المكتبة التي يمكن استخدامها عبر الحدود DLL

وشخصيا، أنا فقط تعريف فئة بسيطة لتوفير وظائف المطلوبة:

class NewDelete
{
    public:
        void *operator new (size_t size);
        void operator delete (void *memory);
        void *operator new (size_t size, void *ptr);
        void operator delete (void *memory, void *ptr);
};

وطالما يتم تحديد كافة هذه الوظائف الأربع الأعضاء في نفس DLL، ثم أي الطبقة التي تستمد من هذه الفئة هي تلقائيا "DLL آمنة" - جديد وحذف يمكن استخدامها عادة عليها دون الحاجة إلى القلق حول حدود DLL.

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