لماذا لا STD :: String :: max_size () == std :: string :: incorator :: max_size ()

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

  •  22-09-2019
  •  | 
  •  

سؤال

لقد لاحظت مؤخرًا أن البيان التالي غير صحيح std::string s.

s.max_size() == s.get_allocator().max_size();

أجد هذا مثيرًا للاهتمام بشكل افتراضي std::string سوف نستخدم std::allocator<char> التي لها حد نظري size_type(-1) (نعم أعلم أنني أفترض تكملة 2 ، لكن هذا لا علاقة له بالسؤال الفعلي). أعلم أن القيود العملية ستكون أقل بكثير من هذا. على نظام X86 32 بت نموذجي ، ستشغل النواة 2 جيجابايت (ربما 1 جيجا بايت) من مساحة العنوان مما يترك حد عملي أصغر بكثير.

على أي حال ، GNU LIBSTDC ++ std::basic_string<>::max_size() يبدو أنه يعيد نفس القيمة بغض النظر عن ما يقوله المخصص الذي يستخدمه (شيء مثل 1073741820).

لذا يبقى السؤال ، لماذا لا std::basic_string<>::max_size() فقط العودة get_allocator().max_size()؟ يبدو لي أن هذا هو الحد الأعلى الافتراضي. وإذا كان التخصيص قصيرًا ، فسوف يلقي فقط std::bad_alloc, ، فلماذا لا تحاول؟

هذا فضول أكثر من أي شيء آخر ، كنت أتساءل فقط لماذا يتم تعريف الاثنين بشكل منفصل في هذا التنفيذ على الأقل.

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

المحلول

في Microsoft Connect تم نشر خطأ يتعلق بسؤالك. لدى Microsoft إجابة مثيرة للاهتمام:

لقد قمنا بحلها حسب التصميم وفقًا لتفسيرنا للمعيار ، وهو ما لا يفسر بوضوح الغرض المقصود لـ max_size (). يوصف مخصص MAX_SIZE () بأنه "أكبر قيمة يمكن تمريرها بشكل مفيد إلى X :: TIMAINT ()" (C ++ 03 20.1.5 [lib.allocator.requirements]/الجدول 32) ، ولكن الحاوية max_size () يوصف بأنه "حجم () لأكبر حاوية ممكنة" (23.1 [lib.container.requirements]/الجدول 65). لا شيء يصف ما إذا كان ينبغي اشتقاق حاوية max_size () من مخصص Max_Size (). لقد استمد تنفيذنا لسنوات عديدة حاوية max_size () مباشرة من مخصص Max_Size () ثم استخدم هذه القيمة لفحوصات الفائض وما إلى ذلك. التفسيرات الأخرى للمعيار ، مثل لك ، ممكنة ، ولكنها ليست صحيحة بشكل لا لبس فيه. يمكن أن تستفيد صياغة المعيار بالتأكيد من التوضيح هنا. ما لم يكن ذلك وحتى حدوث ذلك ، قررنا ترك تنفيذنا الحالي دون تغيير لسببين: (1) قد يكون العملاء الآخرون يعتمدون على سلوكنا الحالي ، (2) MAX_SIZE () لا يشتري أي شيء بشكل أساسي. على الأكثر ، يمكن للأشياء التي تستهلك المخصصين (مثل الحاويات) استخدام مخصص MAX_SIZE () للتنبؤ عند تفشل التخصيص () - ولكن ببساطة استدعاء تخصيص () هو اختبار أفضل ، لأن المخصص سيقرر إعطاء الذاكرة أم لا. يمكن للأشياء التي تستهلك الحاويات استخدام الحاوية max_size () كضمان لكيفية حجم () ، ولكن ضمان أبسط هو نطاق Size_type.

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

إذن إجابة سؤالك "لماذا ..؟" هل هذا المعيار لا يفسر بوضوح الغرض المقصود لـ max_size ().

نصائح أخرى

لست متأكدًا تمامًا ولكن بقدر ما أعرف std::basic_string لا يقتصر في المعيار الحالي لتخزين السلسلة في الذاكرة المستمرة. على سبيل المثال ، قد يخزنها في عدة قطع. ثم يقتصر كل قطعة من هذا القبيل على std::allocator::max_size() لكن المبلغ قد يكون أكبر من ذلك.

كما يبدو أن هذا هو الحال مع حاويات STL. وبعد كل شيء std::basic_string هي حاوية.

يتمتع تطبيق GCC بتعليق على كيفية حسابهم max_size (يتعين على المرء أن يطرح حجم كائن التدبير المنزلي الداخلي الذي يتم تخصيصه ككتلة واحدة مع السلسلة) ، ثم يضيف ذلك max_size() يعود ربع ذلك. لا يوجد سبب منطقي ، لذلك ربما يكون مجرد هامش أمان؟ (يجب أن توفر أيضًا فئة حبل ، والتي ربما يستخدمها المرء للسلاسل الكبيرة؟)

مع VC ++ max_size() يعيد أقل من allocator.max_size() - ربما لحساب إنهاء الشخصية الفارغة.

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