ปัญหาการจัดตำแหน่งชั้นเรียน

ฉันกำลังทดสอบการจัดชั้นเรียนและพบพฤติกรรมแปลกๆ ฉันทดสอบด้วยการตั้งค่าการจัดตำแหน่งคอมไพเลอร์ VS2012 4 และ 8 ไบต์ แต่ในแต่ละกรณีเอาต์พุตจะเหมือนกัน

class Alignemnt{
public:
    Alignemnt():a(){}
    int a;
};

class Alignemnt_1{
public:
    int a;
    char array[2];
};

class Alignemnt_2{
public:
    int a;
    char array[2];
    int x;
};

std::cout <<  "Sizeof(Alignemnt)   :" <<sizeof(Alignemnt) << std::endl;
std::cout <<  "Sizeof(Alignemnt_1) :" <<sizeof(Alignemnt_1) << std::endl;
std::cout <<  "Sizeof(Alignemnt_2) :" <<sizeof(Alignemnt_2) << std::endl;

ทุกครั้งที่ส่งออกคือ:

Sizeof(Alignemnt)   : 4

Sizeof(Alignemnt_1) : 8

Sizeof(Alignemnt_2) : 12

ฉันคิดว่าขนาด Alignemnt_2 ควรเป็น 16 ไบต์


person CrazyC    schedule 29.01.2015    source แหล่งที่มา
comment
ดังนั้นคำถามของคุณคืออะไร? สำหรับฉันดูเหมือนว่าคอมไพเลอร์ทำงานได้ดีใช่ไหม   -  person gha.st    schedule 29.01.2015
comment
ฉันคิดว่าขนาด Alignemnt_2 ควรเป็น 16 ไบต์   -  person CrazyC    schedule 29.01.2015
comment
โดยทั่วไปแล้ว int จะถูกจัดเรียง 4 ไบต์ char[2] เป็นเพียงวัตถุขนาด 2 ไบต์ คุณได้รับขนาด 12 ไบต์เนื่องจาก int แรกใช้ 4 ไบต์ อ็อบเจ็กต์ที่สองใช้ 2 ไบต์ และอันที่สามต้องอยู่ในแนวเดียวกัน 4 ไบต์   -  person Charlie    schedule 29.01.2015
comment
@TonyD Size เป็นผลคูณของการจัดตำแหน่ง ดังนั้นการจัดตำแหน่งจึงส่งผลต่อขนาด และนี่ไม่ได้พูดถึงว่าการจัดตำแหน่ง สมาชิก มีผลกับขนาดของวัตถุที่บรรจุอยู่ด้วยซ้ำ   -  person gha.st    schedule 29.01.2015
comment
บางทีเขาน่าจะลองรวบรวมการทดสอบเพิ่มเติม! หลังจากอ่านแบบเบาๆ ฉันคิดว่าบางทีคอมไพเลอร์ Visual Studio อาจปรับการจัดเก็บข้อมูลให้เหมาะสมด้วยวิธีพิเศษ   -  person Cinch    schedule 29.01.2015
comment
ทำให้ฉันรู้สึกว่าฉันไม่รู้ว่าคุณกำลังใช้การตั้งค่าใดหรือเล่นอย่างไรระหว่างวัตถุกับสมาชิกโครงสร้าง หากสมาชิก struct จำเป็นต้องจัดแนว 8 ไบต์ ดังนั้น #2 จะต้องมีขนาด 24 ไบต์ (หรือ 20 ไบต์) แต่หากการจัดตำแหน่งอยู่ที่ระดับการจัดสรรอ็อบเจ็กต์/หน่วยความจำ ก็จะไม่เปลี่ยนขนาดของคุณ โครงสร้างเลย   -  person Charlie    schedule 29.01.2015
comment
เกินเลยไปเล็กน้อย: คุณสามารถใช้ struct แทน class เพื่อเหตุผลในการทดสอบ เพื่อประหยัดเวลาของคุณด้วยการหลีกเลี่ยงการพิมพ์คำหลัก public   -  person borisbn    schedule 29.01.2015


คำตอบ (3)


ฉันถือว่าคุณกำลังอ้างถึงสวิตช์ /Zp ซึ่งช่วยให้คุณควบคุมได้ สูงสุด การจัดตำแหน่งสมาชิกโครงสร้าง:

เมื่อคุณระบุตัวเลือกนี้ แต่ละสมาชิกของโครงสร้างหลังจากสมาชิกตัวแรกจะถูกเก็บไว้ในขนาดของชนิดสมาชิกหรือขอบเขต n ไบต์ (โดยที่ n คือ 1, 2, 4, 8 หรือ 16) ขึ้นอยู่กับว่าจำนวนใดจะน้อยกว่า

เนื่องจากคุณไม่ได้ใช้สมาชิก struct ที่มีการจัดตำแหน่งมากกว่า 4 ไบต์ (sizeof(int) และ alignof(int) เป็นทั้ง 4) การตั้งค่าทั้งหมดที่มีขนาด 4 ไบต์ขึ้นไปจะนำไปสู่พฤติกรรมที่เหมือนกันทุกประการ

หากคุณต้องการระบุการจัดตำแหน่ง ที่แน่นอน ของสมาชิกโครงสร้าง ให้ลองใช้ alignas ซึ่งช่วยให้คุณระบุการจัดตำแหน่งที่แน่นอนที่สมาชิกควรจะมี (VS 2012 ควรสนับสนุน iirc)

ดูผลลัพธ์ของการใช้ alignas

person gha.st    schedule 29.01.2015

การจัดแนวไม่ควรเปลี่ยนขนาดของวัตถุ แต่เป็นเพียงที่อยู่เริ่มต้นของวัตถุเท่านั้น ตัวอย่างเช่น ออบเจ็กต์ที่จัดแนวขนาด 8 ไบต์อาจเป็นที่อยู่ 0x100000 หรือ 0x100008 หรือที่อยู่ใดๆ ที่ลงท้ายด้วย 0 หรือ 8 เมื่อเขียนด้วยเลขฐานสิบหก แต่ไม่ใช่ 0x100004

person Charlie    schedule 29.01.2015
comment
ฉันไม่เห็นด้วยกับมัน การจัดตำแหน่งเกี่ยวข้องกับช่องว่างภายในซึ่งจะเปลี่ยนขนาดของวัตถุ - person CrazyC; 29.01.2015
comment
นอกจากนี้ ขนาดของวัตถุจะเป็นผลคูณของการจัดตำแหน่ง - person gha.st; 29.01.2015
comment
ใช่. @กา..st. การจัดตำแหน่งจะทำให้ขนาดของวัตถุเป็นไปตามการตั้งค่าหลายค่าเสมอ ที่นี่ฉันสร้างมันขึ้นมา 8 ไบต์ดังนั้นแทนที่จะเป็น 12 ควรเป็น 16 - person CrazyC; 29.01.2015
comment
ขนาดไม่ได้รับผลกระทบจากการจัดตำแหน่ง ประสิทธิภาพของการบรรจุจะได้รับผลกระทบจากการจัดตำแหน่ง แต่ไบต์ที่จำเป็นในการจัดเก็บวัตถุจะไม่ได้รับผลกระทบ ตัวอย่างเช่น หากฉันแพ็ควัตถุที่ต้องจัดแนวขนาด 8 ไบต์ถัดจากสิ่งที่ไม่สนใจ ก็ไม่จำเป็นต้องมีการเสริม - person Charlie; 29.01.2015
comment
@Charlie เว้นแต่ว่าคุณกำลังพูดถึงประเภทที่ซ้อนทับกัน ลองดูที่ ตัวอย่างนี้ ที่ทำอย่างนั้น: แพ็ค วัตถุที่จัดตำแหน่งและมีขนาด 8 ไบต์ถัดจากวัตถุที่มีการจัดตำแหน่งและขนาด 1 ไบต์ ขนาดจะเปลี่ยนจาก 9 ไบต์เป็น 16 ไบต์เมื่อเปลี่ยนการจัดตำแหน่งของสมาชิกตัวแรก - person gha.st; 29.01.2015
comment
@ gha.st ฉันกำลังคิดอะไรบางอย่างในบรรทัดว่าการจัดตำแหน่งจะใช้ที่ระดับโครงสร้างหรือ (เช่นโครงสร้างสามารถจัดแนวได้ 8 ไบต์ แต่การจัดตำแหน่งไม่เป็นไปตามสมาชิก) เทียบกับการจัดตำแหน่งสมาชิก - การจัดตำแหน่งนำไปใช้กับ ระดับโครงสร้างเทียบกับการจัดตำแหน่งที่ใช้กับแต่ละองค์ประกอบ - person Charlie; 29.01.2015

No.

การจัดตำแหน่งที่ 2 เป็นเรื่องปกติ

คุณมีตัวอักษร 2 ตัวติดกัน ซึ่งหมายความว่าคุณใช้ไปแล้ว 2 ใน 4 ไบต์ การบรรจุจะจัดแนวให้เป็น 4 ไบต์แล้วคุณจะจบลงด้วย 4 + 4 +4

หากคุณต้องการที่จะจบลงที่ 16 คุณสามารถลองประกาศต่อไปนี้:

 {
      char a;
      int b;
      char c;
      int d;
 }
person MichaelCMS    schedule 29.01.2015
comment
@CrazyC มีเหตุผลใดที่ทำให้ downvote ? มีอะไรที่ฉันระบุว่าไม่เป็นความจริงหรือไม่? หรือคุณแค่ชอบ downvoting เพื่อประโยชน์ในการ downvoting ? - person MichaelCMS; 29.01.2015
comment
@CrazyC อ่าขอโทษ ฉันคิดว่าคุณลงคะแนนเสียงลง อย่างไรก็ตาม ฉันยังคงอยากรู้ว่าเหตุใดผู้ลงคะแนนเสียงลงคะแนนเสียงลงคะแนน ... - person MichaelCMS; 29.01.2015