المشغل "الجديد" يعيد مؤشر كومة غير محلي لفئة واحدة فقط؟
-
26-09-2019 - |
سؤال
اللغة: C ++
النظام الأساسي: Windows Server 2003
لدي exe استدعاء DLL.
تعديل :(EXE لا تفعل أي شيء ، فهو يدعو الوظائف العالمية القليلة التي تفعل كل ما يتعلق بـ DLL داخل DLL. إنه لا ينطبق بشكل صريح الجديد أي من فئات DLL)
أنا تخصيص (الجديد) ذاكرة الفئة أ داخل DLL ، يعيدني أ مؤشر كومة غير محلي.
انا حاولت الجديد فئات أخرى داخل DLL (وهي في DLL) ، "New" تُرجع مؤشر كومة صالح لهم ، إنه فقط الفئة أ الذي لا يتم تخصيصه بشكل صحيح.
أنا على Windows وأتحقق من صحة الكومة من خلال هذه الوظيفة:
تعديل:
ClassA* pA = new ClassA();
_CrtIsValidHeapPointer ( (const void *) pA )
أنا مرتبك بشكل خطير لماذا يحدث هذا فقط مع الجديد-عمل الفئة أ ولا فئة أخرى؟
(جميع الكود الأصلي)
التحرير النهائي:
اتضح أنه بناء سيء. لا يمكنك الحصول عليه للتكاثر في الجديد ... ضائع 5 أيام على هذا: '(((
المحلول
تصدير الوظائف العالمية فقط من DLLs واستدعاء الوظائف التي تم تصديرها فقط ومن خلال الطاولات V. مشكلتك ليست سوى واحدة من العديد من الناجم عن محاولة تصدير الفصول بأكملها. DLLs ليست هي نفس المكتبات.
تحرير: نظرًا لأن السؤال يكشف الآن أن الفصل لم يتم تصديره ، ولكن يتم ملاحظة كل هذا داخل DLL الفردي ، سيقترح أسبابًا محتملة أخرى.
هو نفس المؤشر الذي عاد منه new
يجري اختباره ، أو هل يمكن أن يكون مؤشرًا إلى كائن فرعي أساسي؟ هل استخدم التخصيص new
أو new []
؟ يمكن أن يتسبب أي من هذه المؤشر إلى الإشارة إلى منتصف كتلة الكومة بدلاً من البداية.
نصائح أخرى
لو Class A
تجاوزات operator new
ثم يمكن تخصيص ذاكرة تلك الفئة في نسخة DLL من وقت التشغيل C. هذا من شأنه أن يسبب _CrtIsValidHeapPointer
لكي ترجع false
- لان لك يستخدم إصدار مكتبة وقت التشغيل C كومة مختلفة عن الإصدار الموجود في DLL.
القيمة التي تم إرجاعها من _CrtIsValidHeapPointer
عمومًا غير موثوق به على أي حال (بالتأكيد ، على الرغم من أنه قد يعود بشكل صحيح ، فإنه لا يعني بالضرورة أنك تستطيع ذلك استعمال المؤشر). لماذا تفعل هذا على أي حال؟
ربما يعلن الفصل مشغله الجديد الذي يحصل على التخزين من بعض موقع الغموض؟
على سبيل المثال ، قد يكون مؤلف الفصل قد كتب:
class MyClass {
public:
void * operator new (size_t amt);
void operator delete(void *);
};
ثم مشغلهم الجديد يتفوق على المشغل الجديد.
إما أن يتم بناء هذا أو DLL باستخدام /mtd بينما الاستخدامات القابلة للتنفيذ /MD.