لماذا يجب استخدام malloc() عند "شار bigchar[ 1u << 31 - 1 ];" يعمل على ما يرام ؟

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

  •  22-07-2019
  •  | 
  •  

سؤال

ما هي الاستفادة من استخدام malloc (إلى جانب NULL العائد على الفشل) على الصفائف ثابتة?البرنامج التالي سوف تلتهم كل ما عندي من ذاكرة الوصول العشوائي و تبدأ في ملء المبادلة إلا إذا كانت الحلقات uncommented.لا تحطم.

...

#include <stdio.h>

unsigned int bigint[ 1u << 29 - 1 ];
unsigned char bigchar[ 1u << 31 - 1 ];

int main (int argc, char **argv) {
  int i;
/*   for (i = 0; i < 1u << 29 - 1; i++) bigint[i] = i; */
/*   for (i = 0; i < 1u << 31 - 1; i++) bigchar[i] = i & 0xFF; */

  getchar();
  return 0;
}

...

بعد بعض التجربة والخطأ وجدت أعلاه هو أكبر ساكنة مجموعة سمحت على 32-bit Intel آلة مع دول مجلس التعاون الخليجي 4.3.هل هذا معيار الحد ، مترجم الحد ، أو آلة الحد ؟ على ما يبدو لا يمكن أن يكون العديد من منهم كما أريد.وسوف segfault, ولكن فقط إذا كنت تسأل عن (أن) أكثر من malloc من شأنه أن يعطي لي على أية حال.

هل هناك طريقة لتحديد ما إذا كان ثابت صفيف تم فعلا تخصيص آمنة للاستخدام ؟

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

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

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

المحلول

حسنا, لسببين حقا:

  1. بسبب قابلية لأن بعض الأنظمة لن تفعل إدارة الذاكرة الظاهرية بالنسبة لك.

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

جميع في كل شيء سوف ينتهي تنفيذ الكثير من الوظائف إدارة الذاكرة (في الواقع الى حد كبير reimplementing على malloc) دون الاستفادة من قابلية.

ومن ثم الأسباب:

  • مدونة قابلية عبر إدارة الذاكرة التغليف و التوحيد.

  • الشخصية وتعزيز الإنتاجية في طريق رمز إعادة استخدامها.

نصائح أخرى

مع malloc هل يمكن أن تنمو وتقليص حجم الصفيف الخاص بك:يصبح ديناميكية بحيث يمكنك تخصيص بالضبط ما تحتاجه.

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

فيما يتعلق:

بعد بعض التجربة والخطأ وجدت أعلاه هو أكبر ثابت صفيف يسمح على 32-bit Intel آلة مع دول مجلس التعاون الخليجي 4.3.هل هذا معيار الحد مترجم الحد ، أو آلة الحد ؟

واحد الحد الأعلى سوف يعتمد على مدى 4 غيغابايت (32-بت) مساحة العنوان الظاهرية مقسمة بين المستخدم مساحة kernel الفضاء.لينكس, وأعتقد الأكثر شيوعا التقسيم المخطط له 3 GB نطاق من عناوين المستخدم مساحة 1 GB نطاق من عناوين نواة الفضاء.التقسيم هو شكلي في نواة بناء-الوقت 2 جيجابايت/2 جيجابايت و 1 جيجابايت/3GB انشقاقات أيضا في استخدام.عندما قابل للتنفيذ يتم تحميل, مساحة العنوان الظاهرية يجب تخصيص لكل كائن بغض النظر عما إذا كانت حقيقية يتم تخصيص الذاكرة التي تعضد هذا الامر.

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

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

لا توجد طريقة مجانية تخصيص مكدس أخرى من الخروج من نطاق.لذلك عندما كنت في الواقع استخدام العالمية وتخصيص VM أن الوك كنت بجد الذاكرة ، فإنه يتم تخصيص و سيبقى هناك حتى البرنامج تنفد.وهذا يعني أن أي عملية سوف تنمو فقط في استخدام الذاكرة الظاهرية (وظائف المحلية كومة مخصصات تلك "تحرير").

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

ثم يتلخص كم الباحث فو[1<<29]'s يمكن أن يكون.منذ أول واحد يأخذ كله الذاكرة (على 32bit) و سوف يكون (يتيح الكذب:0x000000) الثانية سيتم حل إلى 0xffffffff أو thereaobout.ثم الثالث حل ماذا ؟ شيء 32bit مؤشرات لا يمكن التعبير.(تذكر أن كومة التحفظات يتم حلها جزئيا في compiletime جزئيا وقت التشغيل عن طريق إزاحة مدى كومة تعويض يدفع عند الوك هذا أو ذاك متغير).

وبالتالي فإن الجواب هو الى حد كبير أنه بمجرد أن يكون لديك الباحث فو [1<<29] كنت غير قادر على أي عمق معقولة من الوظائف الأخرى المحلية كومة المتغيرات بعد الآن.

كنت حقا ينبغي تجنب القيام بذلك إلا إذا كنت تعرف ما تفعلونه.محاولة فقط طلب الكثير من الذاكرة كما تحتاج.حتى لو كان لا يتم استخدامها أو الحصول على الطريق من البرامج الأخرى التي يمكن أن تصل الفوضى العملية النفس.هناك نوعان من الأسباب لهذا.أولا على أنظمة معينة ، خاصة 32bit منها يمكن أن يسبب مساحة العنوان أن استنفدت قبل الأوان في ظروف نادرة.بالإضافة إلى ذلك العديد من حبات يكون نوعا ما في عملية حد محفوظة/الظاهرية/ليس في استخدام الذاكرة.إذا كان البرنامج يطلب الذاكرة في النقاط في وقت التشغيل kernel يمكن أن تقتل العملية إذا كان يسأل عن الذاكرة المحجوزة تتجاوز هذا الحد.لقد رأيت برامج إما تحطمت أو خرج بسبب فشل malloc لأنهم المتحفظة GBs من الذاكرة في حين فقط باستخدام بضعة ميغابايت.

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