ما هي أسباب الأمراض المنقولة جنسيا::النوع() للوصول إلى عنوان خارج النطاق

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

سؤال

أنا أفهم أن استخدام std::النوع () ، مقارنة وظيفة يجب أن تكون صارمة ضعف النظام, وإلا فإنه سوف تحطم بسبب الوصول إلى عنوان من الالتزام.(https://gcc.gnu.org/ml/gcc-bugs/2013-12/msg00333.html)

ولكن لماذا std::النوع() الوصول غير ملزمة عنوان عندما قارن بين وظيفة ليست صارمة ضعف النظام ؟ ماذا يحاول أن تقارن ؟

أيضا أنا أتساءل عما إذا كان هناك مطبات أخرى في المحكمة الخاصة بلبنان التي يجب أن تكون على علم.

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

المحلول

أول شيء هو أن الدعوة الخوارزمية مع المقارنة التي لا تتوافق مع متطلبات غير معرف سلوك كل شيء مباح...

ولكن بخلاف ذلك, أعتقد أن كنت ترغب في معرفة ما هو نوع من التنفيذ قد ينتهي الوصول إلى خارج الحدود إذا كانت المقارنة هو سيء. يجب تنفيذ التحقق من الحدود قبل الوصول إلى العناصر في المقام الأول ؟ أيقبل استدعاء المقارنة

الجواب هو الأداء, و هذا هو مجرد واحدة من الأشياء الممكنة التي يمكن أن تؤدي إلى هذا النوع من القضايا.هناك تطبيقات مختلفة من خوارزميات الفرز ، ولكن في أكثر الأحيان ، std::sort هو مبني على رأس البديل من فرز سريع من شأنها أن تتحول في مختلف خوارزمية الفرز مثل mergesort لتجنب فرز سريع أسوأ الأحوال الأداء.

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

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

while (pos < end && value(pos) < pivot) { ++pos; }

بينما في عام التقسيم لا يمكن أن نفترض أن القيمة المحورية سوف تكون في مجموعة ، فرز سريع يعرف أنه بعد كل ذلك اختيار محور من العناصر في مجموعة.مشترك الأمثل في هذه الحالة هو مبادلة قيمة متوسط في العنصر الأخير من الحلقة.هذا يضمن أن value(pos) < pivot وسوف يكون ذلك صحيحا قبل pos == end (أسوأ الأحوال: pos == end - 1).والمعنى الضمني هنا هو أن نتمكن من إسقاط التحقق من نهاية نطاق يمكننا استخدام unchecked_partition (اختر من الاسم) مع أبسط وأسرع الحالة:

while (/*pos < end &&*/ value(pos) < pivot) ++pos;

كل شيء جيد تماما ، إلا أن < هو مكتوبة comparator(value(pos), pivot).الآن إذا كان comparator بشكل غير صحيح تنفيذها كنت قد ينتهي مع comparator(pivot,pivot) == true و المؤشر سوف تعمل خارج الحدود.

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

نعود إلى السؤال:

يجب تنفيذ التحقق من الحدود قبل الوصول إلى العناصر في المقام الأول ؟ أيقبل استدعاء المقارنة

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

نصائح أخرى

std::sort لا بل تتطلب أن تعطى المقارنة يحدد صارمة ضعف الطلب ، وإلا الفرز لا معنى كبير.

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

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

كما تجنب "مطبات" فقط يكون على بينة من متطلبات الخوارزميات و المهام التي يمكنك استخدامها.C++ وهناك لطيفة الإشارة الموقع الذي أنا عادة استخدام: cppreference

والتي على صفحة std::sort يقول:

شركات - وظيفة مقارنة كائن (أيالكائن الذي يلبي متطلبات مقارنة) التي تقوم بإرجاع true إذا كانت الحجة الأولى هي أقل من (أيهو أمر قبل أن) الثاني.

مع وصلة إلى وصف قارن

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