يمكن C المصفوفات تحتوي على الحشو بين عناصر؟

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

  •  21-08-2019
  •  | 
  •  

سؤال

وسمعت إشاعة أن، في C، صفائف المضمنة داخل البنيات قد الحشو وأضاف في بين عناصر المصفوفة. الآن من الواضح، كمية من الحشو لا يمكن أن تختلف بين أي زوج من العناصر أو حساب العنصر التالي في مجموعة غير ممكن مع الحساب مؤشر بسيط.

وذكر هذه الشائعات أيضا أن المصفوفات التي لا ترد في هياكل مضمونة للا تحتوي على الحشو. وأنا أعلم ما لا يقل عن هذا الجزء هو الصحيح.

وهكذا، في رمز، والشائعات هي:

{
    // Given this:
    struct { int values[20]; } foo;
    int values[20];

    // This may be true:
    sizeof(values) != sizeof(foo.values);
}

وأنا واثق تماما من أن sizeof(values) سوف أكون دائما على قدم المساواة sizeof(foo.values). ومع ذلك، لم أكن قادرا على العثور على أي شيء في مستوى C (على وجه التحديد C99) الذي يؤكد صراحة أو تنفي ذلك.

لا أحد يعرف إذا تم تناول هذه الشائعات في أي مستوى C؟

تعديل : لأفهم أنه قد يكون هناك مسافة بين نهاية foo.values مجموعة ونهاية foo البنية وأن الدول القياسية التي من شأنها أن تكون هناك مسافة بين بداية foo و بداية foo.values. ومع ذلك، لا أحد يملك <م> اقتبس من أو <م> إشارة إلى المعيار حيث تقول ليس هناك مسافة بين عناصر foo.values؟

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

المحلول

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

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

نصائح أخرى

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

في المثال الخاص بك، فإن values وfoo.values صفائف لها نفس الحجم. فإن أي الحشو تكون جزءا من foo البنية بدلا من ذلك.

وهنا يكمن تفسير ل<م> لماذا هيكل قد تحتاج الحشو بين أعضائه أو حتى بعد عضوا الأخير، والسبب في ذلك مجموعة لا:

قد يكون

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

(struct foo *)((char *)bar + sizeof(struct foo))

وتعطي مؤشر صالح لstruct foo (أي لا تفشل بسبب سوء التوافق).

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

نعم، نوعا ما. وغالبا ما يتم محاذاة المتغيرات لبعض boundry، اعتمادا على المتغير. خذ ما يلي على سبيل المثال:

typedef struct
{
    double d;
    char c;
} a_type_t;

وضعف وشار و8 و 1 بايت، على نظام بلدي، على التوالي. مجموعه 9. هذا الهيكل، ومع ذلك، سوف يكون 16 بايت، بحيث الزوجي ستكون دائما 8 بايت الانحياز. وإذا كان لي فقط [إينتس] المستخدمة، حرف، وما إلى ذلك، ثم محاذاة قد يكون 1، 2، 4، أو 8.

لنوع T، sizeof(T) <م> قد تكون أو لا يساوي sizeof(T.a) + sizeof(T.b) + sizeof(T.c) ... الخ.

وعموما، هذا هو مترجم تماما والهندسة المعمارية التابعة. في الممارسة العملية، فإنه لا يهم.

والنظر فيما يلي:

struct {
  short s;
  int i;
} s;

وعلى افتراض القصيرة هي 16 بت، وكنت على 32 بت، وحجم و<م> ربما أن يكون 8 بايت كما يميل كل أعضاء البنية إلى الانحياز كلمة (32 بت في هذه الحالة) الحدود. وأقول "ربما" لأنه هو تنفيذ السلوك المحددة التي يمكن أن تختلف من الأعلام المترجم، وما شابه ذلك.

ومن الجدير مؤكدا أن هذا هو السلوك تنفيذ لا يعرف بالضرورة وفق المعايير C. يشبه إلى حد كبير حجم السراويل القصيرة، [إينتس] ويتوق (معيار C تقول ببساطة سوف السراويل لا تكون أكبر من و[إينتس] ويتوق لا تكون أصغر من [إينتس]، والتي يمكن في نهاية المطاف كما 16/32/32، 16/32/64 ، 32/32/64 أو عدد من تكوينات أخرى).

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