ما هي الطريقة الصحيحة لتهيئة البنية كبيرة جدا؟

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

  •  05-07-2019
  •  | 
  •  

سؤال

في رمز لنا نحن كانت لدينا شيء من هذا القبيل:

   *(controller->bigstruct) = ( struct bigstruct ){ 0 };

ويستخدم هذا العمل العظيم، وبعد ذلك ترقية الإصدارات من دول مجلس التعاون الخليجي والتي فجأة نرى تجاوزات المكدس. وعند النظر إلى التجمع، رمز دول مجلس التعاون الخليجي القديم (الإصدار 2.x) كان يقوم به أساسا هذا:

memset(controller->bigstruct, 0, sizeof(struct bigstruct));

ودول مجلس التعاون الخليجي الجديد (3.4.x) كان يقوم به هذا

   struct bigstruct temp = { 0 };
   controller->bigstruct = temp;

وبعد مراجعة المواصفات C99، استطعت أن أرى لماذا. C99 يتطلب أساسا أن هياكل مجهولة موجودة على المكدس. انها فكرة جيدة، ولكن كان هذا الهيكل 4 ميغابايت كبير، وفقط المقصود من أي وقت مضى في الوجود على كومة!

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

ما هو "تصحيح"، أو على الأقل أفضل، وسيلة لتهيئة بنية كبير مثل هذا؟

لتوضيح فورثور لماذا أعتقد memset ليس حلا: قواعد التهيئة من الأعضاء لا تهيئة صراحة هي نفس التهيئة ثابتة، وهي كالتالي:    - إذا كان لديه نوع المؤشر، يتم تهيئة لمؤشر فارغة؛    - إذا كان لديه نوع الحسابي، وتهيئته ل(إيجابية أو غير موقعة) صفر.    ...

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

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

المحلول

وmemset هو الطريق للذهاب. لم يكن لديك العديد من البدائل.

ونفعل شيئا مثل:

#define InitStruct(var, type) type var; memset(&var, 0, sizeof(type))

وحتى ان كنت لا تملك إلا أن:

InitStruct(st, BigStruct);

وبعد ذلك استخدام الحادي وكالعادة ...

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

وعلاوة على ذلك - وهذا هو نفس المنطق الذي استخدمته عند القيام

*(controller->bigstruct) = *( struct bigstruct ){ 0 };

لذلك أنا لا تحصل على التردد الخاص بك لاستخدامه:)

وجعلت أول تعليق لهذا المنصب لي القيام ببعض الأبحاث قبل دعوت له واحمق ولقد وجدت هذا:

http://www.lysator.liu.se/ ج / ج-أسئلة وأجوبة / ج-1.html

ومثيرة جدا للاهتمام. إذا كان بإمكاني التصويت المتابعة تعليق أود أن:)

وأن يقال - الخيار الوحيد الخاص بك إذا كنت ترغب في استهداف أبنية قديمة مع 0 غير القيم الخالية لا يزال إلى القيام التهيئة اليدوية لبعض أعضاء

وبفضل توماس بادرون-مكارثي! تعلمت شيئا جديدا اليوم:)

نصائح أخرى

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

وقال إنه إذا كان مجلس التعاون الخليجي باستخدام memset، وكانت جيدة بما فيه الكفاية سابقا، أود أن أقترح انه لامر جيد بما فيه الكفاية الآن.

وكما قال آخرون، memset هو الطريق للذهاب. ومع ذلك، <م> لا استخدام memset على C ++ الأشياء، لا سيما مع وسائل الظاهري. وسوف تشمل sizeof( foo ) جدول مؤشرات دالة الظاهري، وسوف تفعل memset على أن يسبب الحزن الشديد.

إذا لم memset يحل مشكلة في حد ذاته، ببساطة القيام memset و<م> ثم تهيئة أي أعضاء ينبغي أن يكون الصفر غير (أي: دون IEEE القيم نقطة عائمة).

والخاصة وظيفة التهيئة ليست قبيحة بدلا طريقة OO جيدة لتهيئة الكائنات (البنيات). وأفترض أن الهيكل الخاص ليس 4MB من المؤشرات، لذلك أود أن نفترض أن الحل يجب أن يكون مثل هذا:

void init_big_struct(struct bigstruct *s)  
{  
    memset(s, 0, sizeof(struct bigstruct));  
    s->some_pointer = NULL; // Multiply this as needed  
}

من ناحية أخرى يعمل نظامنا على أكثر من 20 جزءا لا يتجزأ من أنظمة التشغيل وعدد كبير من الاجهزه المختلفة، لا يلتقيان أبدا أي مشكلة مع memset فقط من البنية.

وهم - أولا وقبل كل إجراء وظيفة الحرف الأول ووضع كل عضو صراحة هو الشيء الصحيح - هو، ق الطريق المنشئات في اللغات OO تعمل

ووالثانية - لا أحد يعرف على الأجهزة التي تطبق أرقام غير IEEE النقطة العائمة؟ - ربما الكومودور 64 أو somethig؛ -)

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