คำถามติดแท็ก memory-layout

3
เค้าโครงหน่วยความจำโครงสร้างใน C
ฉันมีพื้นหลัง C # ฉันเป็นมือใหม่มากสำหรับภาษาระดับต่ำเช่น C ใน C # structหน่วยความจำของคอมไพเลอร์จะจัดวางโดยค่าเริ่มต้น คอมไพเลอร์สามารถเรียงลำดับฟิลด์ข้อมูลใหม่หรือวางบิตเพิ่มเติมระหว่างฟิลด์โดยปริยาย ดังนั้นฉันต้องระบุแอตทริบิวต์พิเศษบางอย่างเพื่อแทนที่พฤติกรรมนี้สำหรับรูปแบบที่แน่นอน AFAIK, C จะไม่เรียงลำดับใหม่หรือจัดรูปแบบหน่วยความจำของ a structตามค่าเริ่มต้น อย่างไรก็ตามฉันได้ยินมาว่ามีข้อยกเว้นเล็กน้อยที่หาได้ยากมาก ลักษณะการจัดวางหน่วยความจำของ C คืออะไร? สิ่งที่ควรเรียงใหม่ / จัดตำแหน่งและไม่?

7
การเปรียบเทียบตัวชี้ทำงานใน C อย่างไร การเปรียบเทียบพอยน์เตอร์ที่ไม่ได้ชี้ไปที่อาเรย์นั้นเป็นสิ่งที่ดีหรือไม่?
ใน K&R (ภาษาการเขียนโปรแกรม C รุ่นที่ 2) บทที่ 5 ฉันอ่านต่อไปนี้: ขั้นแรกให้เปรียบเทียบตัวชี้ภายใต้สถานการณ์บางอย่าง ถ้าpและqชี้ไปที่สมาชิกของอาร์เรย์เดียวกันแล้วความสัมพันธ์ที่ชอบ==, !=, <, >=ฯลฯ การทำงานอย่างถูกต้อง ซึ่งดูเหมือนว่าบ่งบอกว่ามีเพียงพอยน์เตอร์ที่ชี้ไปยังอาร์เรย์เดียวกันเท่านั้นที่สามารถเปรียบเทียบได้ อย่างไรก็ตามเมื่อฉันลองใช้รหัสนี้ char t = 't'; char *pt = &t; char x = 'x'; char *px = &x; printf("%d\n", pt > px); 1 ถูกพิมพ์ไปที่หน้าจอ ก่อนอื่นฉันคิดว่าฉันจะไม่ได้กำหนดหรือบางประเภทหรือข้อผิดพลาดเพราะptและpxไม่ได้ชี้ไปที่อาร์เรย์เดียวกัน (อย่างน้อยก็ในความเข้าใจของฉัน) เป็นpt > pxเพราะพอยน์เตอร์ทั้งสองชี้ไปที่ตัวแปรที่เก็บอยู่ในสแต็กและสแต็กโตขึ้นดังนั้นที่อยู่หน่วยความจำของtมากกว่าที่อยู่x? อะไรคือสาเหตุที่pt > pxแท้จริง ฉันสับสนมากขึ้นเมื่อนำ malloc เข้ามานอกจากนี้ใน …

2
[[no_unique_address]] และสองค่าสมาชิกประเภทเดียวกัน
ฉันกำลังเล่นกับสิ่งต่อไปนี้[[no_unique_address]]ในc++20 ในตัวอย่างในcppreferenceเรามีประเภทEmptyและประเภทที่ว่างเปล่าZ struct Empty {}; // empty class struct Z { char c; [[no_unique_address]] Empty e1, e2; }; เห็นได้ชัดว่าขนาดของZต้องมีอย่างน้อย2เพราะประเภทe1และe2เหมือนกัน อย่างไรก็ตามฉันต้องการมีZขนาด1จริงๆ นี้มีฉันคิดสิ่งที่เกี่ยวกับการวางรูปภาพEmptyในชั้นเรียนเสื้อคลุมบางคนที่มีพารามิเตอร์แม่แบบพิเศษที่บังคับใช้ประเภทต่าง ๆและe1e2 template <typename T, int i> struct Wrapper : public T{}; struct Z1 { char c; [[no_unique_address]] Wrapper<Empty,1> e1; [[no_unique_address]] Wrapper<Empty,2> e2; }; น่าเสียดาย, sizeof(Z1)==2. มีเคล็ดลับในการทำให้ขนาดZ1เป็นที่หนึ่งหรือไม่? ฉันกำลังทดสอบสิ่งนี้ด้วยgcc version 9.2.1และclang …

1
ทำไมการปรับฐานว่างเปล่าจึงถูกห้ามเมื่อคลาสฐานที่ว่างเปล่าเป็นตัวแปรสมาชิกด้วย?
การเพิ่มประสิทธิภาพฐานที่ว่างเปล่าดีมาก อย่างไรก็ตามมันมาพร้อมกับข้อ จำกัด ดังต่อไปนี้: การเพิ่มประสิทธิภาพฐานว่างเปล่าเป็นสิ่งต้องห้ามหากหนึ่งในคลาสฐานที่ว่างเปล่าเป็นชนิดหรือฐานของประเภทของข้อมูลสมาชิกไม่คงที่ครั้งแรกเนื่องจาก subobjects ฐานสองประเภทเดียวกันจะต้องมีที่อยู่ที่แตกต่างกันภายในการแสดงวัตถุ ประเภทที่ได้รับมากที่สุด เพื่ออธิบายข้อ จำกัด นี้ให้พิจารณารหัสต่อไปนี้ static_assertจะล้มเหลว ในขณะที่การเปลี่ยนแปลงอย่างใดอย่างหนึ่งFooหรือBarเพื่อสืบทอดจากBase2จะเป็นการหลีกเลี่ยงข้อผิดพลาด: #include <cstddef> struct Base {}; struct Base2 {}; struct Foo : Base {}; struct Bar : Base { Foo foo; }; static_assert(offsetof(Bar,foo)==0,"Error!"); ฉันเข้าใจพฤติกรรมนี้อย่างสมบูรณ์ สิ่งที่ฉันไม่เข้าใจคือสาเหตุพฤติกรรมนี้โดยเฉพาะอย่างยิ่งที่มีอยู่ เห็นได้ชัดว่ามีการเพิ่มเข้ามาด้วยเหตุผลเนื่องจากเป็นการเพิ่มที่ชัดเจนไม่ใช่การกำกับดูแล เหตุผลนี้คืออะไร โดยเฉพาะอย่างยิ่งทำไม subobjects ทั้งสองควรจะต้องมีที่อยู่ที่แตกต่างกัน? ในข้างต้นBarเป็นประเภทและfooเป็นตัวแปรสมาชิกประเภทนั้น ฉันไม่เห็นว่าทำไมชั้นฐานของBarเรื่องถึงชั้นฐานของประเภทfooหรือในทางกลับกัน อันที่จริงฉันมีอะไรถ้าฉันคาดหวังว่า&fooจะเป็นเช่นเดียวกับที่อยู่ของBarอินสแตนซ์ที่มีมัน - มันจะต้องอยู่ในสถานการณ์อื่น(1) (1)หลังจากทั้งหมดฉันไม่ได้ทำอะไรแฟนซีกับการvirtualสืบทอดคลาสพื้นฐานว่างเปล่าโดยไม่คำนึงถึงและการคอมไพล์ด้วยBase2แสดงว่าไม่มีอะไรแตกในกรณีนี้โดยเฉพาะ แต่ชัดเจนว่าเหตุผลนี้ไม่ถูกต้องอย่างใดอย่างหนึ่งและมีสถานการณ์อื่น ๆ …
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.