لماذا هيكل يتكون من char ، قصيرة ، و char (بهذا الترتيب) ، عندما تم تجميعه في C ++ مع تمكين التعبئة 4 بايت ، وصول إلى بنية 6 بايت؟

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

سؤال

اعتقدت أنني فهمت كيف تم التعامل مع C/C ++ معالجة عضو الهيكل. لكنني أحصل على نتائج غريبة لترتيب معين في Visual Studio 2008 و 2010.

على وجه التحديد ، أجد أن البنية التي تتكون من char ، قصيرة ، ويتم تجميعها في بنية 6 بايت ، حتى مع تمكين التعبئة من 4 أو 8 بايت. أنا في حيرة من السبب وراء ذلك. أستطيع أن أفهم بنية 4 بايت. ربما أستطيع أن أفهم بنية 8 بايت. لكنني أعتقد أن البنية 6 بايت سيكون مستحيلًا عند تمكين التعبئة 4 بايت.

البرنامج الذي يوضح المشكلة هو:

#include <iostream>
using namespace std;

#pragma pack (4)

struct Alignment
{
 char c1;
 short s;
 char c2;
};

#define REPORT_VAR_POSITION( structName, varName ) cout << "Member '" << #varName << "' sits at byte # " << offsetof( structName, varName ) << "." << endl;

int main(int argc, char* argv[])
{
 cout << "Sizeof struct Alignment is " << sizeof( Alignment ) << " bytes." << endl;
 REPORT_VAR_POSITION( Alignment, c1 );
 REPORT_VAR_POSITION( Alignment, s );
 REPORT_VAR_POSITION( Alignment, c2 );

 system( "pause" );

 return 0;
}

الإخراج هو:

Sizeof struct Alignment is 6 bytes.
Member 'c1' sits at byte # 0.
Member 's' sits at byte # 2.
Member 'c2' sits at byte # 4.
Press any key to continue . . .

هل يمكن لأي شخص أن يشرح لماذا يقوم VC بتعبئة كل من هذه الشورات ببايت إضافي؟

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

المحلول

من وثائق MSDN ل #pragma pack (أين n هي القيمة التي حددتها):

ستكون محاذاة عضو على حدود إما مضاعفة n أو مضاعف حجم العضو ، أيهما أصغر.

sizeof(short) هو بايتان ، وهو أصغر من قيمة التعبئة لأربعة بايتات التي قمت بتعيينها ، لذلك short يتماشى العضو مع حدود بايت.

الاخير char (c2) مبطنة ببايت إضافي بعد ذلك عندما Alignment يتم وضع الكائنات في صفيف ، short لا يزال العنصر محاذاة بشكل صحيح على حدود ثنائية البايت. عناصر الصفيف متجاورة ولا يمكن أن يكون هناك حشوة بينهما ، لذلك يجب إضافة الحشو إلى نهاية الهيكل من أجل ضمان المحاذاة المناسبة في المصفوفات.

نصائح أخرى

على ما يبدو ، أنت بالفعل يسيء فهمه. في Visual Studio لا يمكنك زيادة متطلبات المحاذاة لأعضاء بنية من أي نوع باستخدام إعدادات تعبئة الهيكل. تستطيع فقط تخفيض هم.

إذا كان بنيتك يتكون من char (محاذاة عند 1 بايت حدود) و short (محاذاة عند حدود 2 بايت) ، فإن استخدام إعدادات التعبئة 4 و 8 بايت لن يكون له أي تأثير على تخطيط الهيكل الخاص بك. ستكون النتيجة هي نفسها تمامًا كما هو الحال مع التعبئة 2 بايت. سيكون هيكل حجم 6 بايت.

إعداد التعبئة الوحيد الذي سيكون له أي تأثير في هذه الحالة هو إعداد التعبئة 1 بايت والذي سوف تخفيض متطلبات المحاذاة short من 2 إلى 1 وتؤدي إلى 4 بايت حجم الهيكل.

برنامج التحويل البرمجي C Visual Studio مع خيار الأمر /zp [n] حيث يتم تعبئة البنية على أ نحدود بايت ، هذا هو المكان #pragma pack يأتي التوجيه ، ويتم محاذاة أعضاء الهيكل على حدود مضاعفة n.

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