โครงสร้างช่องว่างภายในและการบรรจุ


209

พิจารณา:

struct mystruct_A
{
   char a;
   int b;
   char c;
} x;

struct mystruct_B
{
   int b;
   char a;
} y;

ขนาดของโครงสร้างคือ 12 และ 8 ตามลำดับ

โครงสร้างเหล่านี้มีเบาะหรือบรรจุ?

การขยายหรือการบรรจุเกิดขึ้นเมื่อใด



24
ศิลปะที่หายไปของการจัดโครงสร้าง C - catb.org/esr/structure-packing
เปาโล

paddingทำให้สิ่งที่ใหญ่กว่า packingทำให้สิ่งเล็กลง แตกต่างกันอย่างสิ้นเชิง.
smwikipedia

คำตอบ:


264

Padding จัดสมาชิกโครงสร้างให้อยู่ในขอบเขตที่อยู่ "เป็นธรรมชาติ" กล่าวคือintสมาชิกจะมีออฟเซ็ตซึ่งอยู่mod(4) == 0บนแพลตฟอร์ม 32- บิต การเว้นวรรคเปิดอยู่ตามค่าเริ่มต้น มันแทรก "ช่องว่าง" ต่อไปนี้ลงในโครงสร้างแรกของคุณ:

struct mystruct_A {
    char a;
    char gap_0[3]; /* inserted by compiler: for alignment of b */
    int b;
    char c;
    char gap_1[3]; /* -"-: for alignment of the whole struct in an array */
} x;

ในทางกลับกันการบรรจุป้องกันไม่ให้คอมไพเลอร์ทำการแพ็ดดิ้ง - สิ่งนี้จะต้องได้รับการร้องขออย่างชัดเจน - ภายใต้ GCC มัน__attribute__((__packed__))ดังต่อไปนี้:

struct __attribute__((__packed__)) mystruct_A {
    char a;
    int b;
    char c;
};

จะผลิตโครงสร้างขนาด 6บนสถาปัตยกรรม 32 บิต

แม้ว่าการบันทึก - การเข้าถึงหน่วยความจำที่ไม่ได้จัดแนวนั้นจะช้ากว่าสำหรับสถาปัตยกรรมที่อนุญาต (เช่น x86 และ amd64) และเป็นสิ่งต้องห้ามอย่างชัดเจนสำหรับสถาปัตยกรรมการจัดตำแหน่งที่เข้มงวดเช่น SPARC


2
ฉันสงสัยว่า: การห้ามหน่วยความจำที่ไม่ได้จัดแนวบนประกายหมายความว่าไม่สามารถจัดการกับอาร์เรย์ไบต์ปกติได้หรือไม่ โครงสร้างการจัดเก็บตามที่ฉันรู้ส่วนใหญ่ใช้ในการส่งข้อมูล (เช่นเครือข่าย) ข้อมูลเมื่อคุณต้องการส่งอาร์เรย์ไบต์ไปยังโครงสร้างและต้องแน่ใจว่าอาร์เรย์เหมาะสมกับเขตข้อมูล struct หากประกายไฟไม่สามารถทำเช่นนั้นได้อย่างไรผู้ที่ทำงานทั้งหมด!
Hi-Angel

14
นั่นเป็นเหตุผลว่าทำไมหากคุณดูที่โครงร่างส่วนหัว IP, UDP และ TCP คุณจะเห็นว่าฟิลด์จำนวนเต็มทั้งหมดอยู่ในแนวเดียวกัน
Nikolai Fetissov

17
The "Lost Art of C Structure Packing" อธิบายการเติมและการบรรจุ ptimisations - catb.org/esr/structure-packing
Rob11311

3
สมาชิกรายแรกต้องมาก่อนหรือไม่? ฉันคิดว่าการจัดการนั้นขึ้นอยู่กับการนำไปใช้ทั้งหมดและไม่สามารถพึ่งพาได้ (แม้จะเป็นเวอร์ชั่น)
allyourcode

4
+ allyourcode มาตรฐานรับประกันว่าคำสั่งของสมาชิกจะถูกเก็บไว้และสมาชิกรายแรกจะเริ่มที่ 0 ออฟเซ็ต
martinkunev

64

( คำตอบข้างต้นอธิบายเหตุผลค่อนข้างชัดเจน แต่ดูเหมือนจะไม่ชัดเจนเกี่ยวกับขนาดของช่องว่างภายในดังนั้นฉันจะเพิ่มคำตอบตามสิ่งที่ฉันเรียนรู้จากThe Lost Art of Structure Packingมันมีวิวัฒนาการไม่ จำกัดCแต่ ยังใช้กับGo, Rust. )


จัดหน่วยความจำ (สำหรับ struct)

กฎ:

  • ก่อนที่สมาชิกแต่ละคนจะมีช่องว่างภายในเพื่อให้เริ่มต้นจากที่อยู่ที่สามารถแบ่งได้ตามขนาดของมัน
    เช่นในระบบ 64 บิตintควรเริ่มที่ที่อยู่หารด้วย 4 และlong8 shortด้วย 2
  • char และ char[]เป็นพิเศษอาจเป็นที่อยู่หน่วยความจำใด ๆ ดังนั้นพวกเขาจึงไม่ต้องการช่องว่างภายในก่อนหน้าพวกเขา
  • สำหรับstructนอกเหนือจากการจัดตำแหน่งที่จำเป็นสำหรับสมาชิกแต่ละคนขนาดของโครงสร้างทั้งหมดจะถูกจัดให้อยู่ในขนาดที่หารได้ตามขนาดของสมาชิกรายใหญ่ที่สุดโดยการขยายที่ท้าย
    เช่นถ้าสมาชิกที่ใหญ่ที่สุดของ struct ก็จะlongหารด้วย 8 intจากนั้นเป็น 4 จากนั้นเท่ากับshort2

คำสั่งของสมาชิก:

  • ลำดับของสมาชิกอาจส่งผลกระทบต่อขนาดของโครงสร้างจริงดังนั้นควรคำนึงถึงสิ่งนั้นด้วย เช่นstu_cและstu_dจากตัวอย่างด้านล่างมีสมาชิกเหมือนกัน แต่ในลำดับที่ต่างกันและส่งผลให้มีขนาดแตกต่างกันสำหรับ 2 struct

ที่อยู่ในหน่วยความจำ (สำหรับ struct)

กฎ:

  • ที่
    อยู่โครงสร้างระบบ 64 บิตเริ่มต้นจาก(n * 16)ไบต์ ( คุณสามารถเห็นในตัวอย่างด้านล่างทั้งหมดที่อยู่ hex พิมพ์ structs จบลงด้วย0. )
    เหตุผล : ที่ใหญ่ที่สุดที่เป็นไปได้สมาชิก struct บุคคลคือ 16 ไบต์ ( long double)
  • (อัปเดต)หากโครงสร้างมีเพียงcharสมาชิกในฐานะที่อยู่ของมันสามารถเริ่มต้นที่ที่อยู่ใดก็ได้

พื้นที่ว่าง :

  • ช่องว่างระหว่าง 2 structs สามารถนำมาใช้โดยตัวแปรที่ไม่ใช่โครงสร้างที่อาจพอดี.
    เช่นในtest_struct_address()ด้านล่างตัวแปรxอยู่ระหว่าง struct ที่อยู่ติดกันและg ไม่ว่าจะมีการประกาศที่อยู่ของจะไม่เปลี่ยนแปลงเพียงนำพื้นที่ว่างที่สูญเปล่ากลับมาใช้ใหม่ กรณีที่คล้ายกันสำหรับ h
    xhxg
    y

ตัวอย่าง

( สำหรับระบบ 64 บิต )

memory_align.c :

/**
 * Memory align & padding - for struct.
 * compile: gcc memory_align.c
 * execute: ./a.out
 */ 
#include <stdio.h>

// size is 8, 4 + 1, then round to multiple of 4 (int's size),
struct stu_a {
    int i;
    char c;
};

// size is 16, 8 + 1, then round to multiple of 8 (long's size),
struct stu_b {
    long l;
    char c;
};

// size is 24, l need padding by 4 before it, then round to multiple of 8 (long's size),
struct stu_c {
    int i;
    long l;
    char c;
};

// size is 16, 8 + 4 + 1, then round to multiple of 8 (long's size),
struct stu_d {
    long l;
    int i;
    char c;
};

// size is 16, 8 + 4 + 1, then round to multiple of 8 (double's size),
struct stu_e {
    double d;
    int i;
    char c;
};

// size is 24, d need align to 8, then round to multiple of 8 (double's size),
struct stu_f {
    int i;
    double d;
    char c;
};

// size is 4,
struct stu_g {
    int i;
};

// size is 8,
struct stu_h {
    long l;
};

// test - padding within a single struct,
int test_struct_padding() {
    printf("%s: %ld\n", "stu_a", sizeof(struct stu_a));
    printf("%s: %ld\n", "stu_b", sizeof(struct stu_b));
    printf("%s: %ld\n", "stu_c", sizeof(struct stu_c));
    printf("%s: %ld\n", "stu_d", sizeof(struct stu_d));
    printf("%s: %ld\n", "stu_e", sizeof(struct stu_e));
    printf("%s: %ld\n", "stu_f", sizeof(struct stu_f));

    printf("%s: %ld\n", "stu_g", sizeof(struct stu_g));
    printf("%s: %ld\n", "stu_h", sizeof(struct stu_h));

    return 0;
}

// test - address of struct,
int test_struct_address() {
    printf("%s: %ld\n", "stu_g", sizeof(struct stu_g));
    printf("%s: %ld\n", "stu_h", sizeof(struct stu_h));
    printf("%s: %ld\n", "stu_f", sizeof(struct stu_f));

    struct stu_g g;
    struct stu_h h;
    struct stu_f f1;
    struct stu_f f2;
    int x = 1;
    long y = 1;

    printf("address of %s: %p\n", "g", &g);
    printf("address of %s: %p\n", "h", &h);
    printf("address of %s: %p\n", "f1", &f1);
    printf("address of %s: %p\n", "f2", &f2);
    printf("address of %s: %p\n", "x", &x);
    printf("address of %s: %p\n", "y", &y);

    // g is only 4 bytes itself, but distance to next struct is 16 bytes(on 64 bit system) or 8 bytes(on 32 bit system),
    printf("space between %s and %s: %ld\n", "g", "h", (long)(&h) - (long)(&g));

    // h is only 8 bytes itself, but distance to next struct is 16 bytes(on 64 bit system) or 8 bytes(on 32 bit system),
    printf("space between %s and %s: %ld\n", "h", "f1", (long)(&f1) - (long)(&h));

    // f1 is only 24 bytes itself, but distance to next struct is 32 bytes(on 64 bit system) or 24 bytes(on 32 bit system),
    printf("space between %s and %s: %ld\n", "f1", "f2", (long)(&f2) - (long)(&f1));

    // x is not a struct, and it reuse those empty space between struts, which exists due to padding, e.g between g & h,
    printf("space between %s and %s: %ld\n", "x", "f2", (long)(&x) - (long)(&f2));
    printf("space between %s and %s: %ld\n", "g", "x", (long)(&x) - (long)(&g));

    // y is not a struct, and it reuse those empty space between struts, which exists due to padding, e.g between h & f1,
    printf("space between %s and %s: %ld\n", "x", "y", (long)(&y) - (long)(&x));
    printf("space between %s and %s: %ld\n", "h", "y", (long)(&y) - (long)(&h));

    return 0;
}

int main(int argc, char * argv[]) {
    test_struct_padding();
    // test_struct_address();

    return 0;
}

ผลการดำเนินการ - test_struct_padding():

stu_a: 8
stu_b: 16
stu_c: 24
stu_d: 16
stu_e: 16
stu_f: 24
stu_g: 4
stu_h: 8

ผลการดำเนินการ - test_struct_address():

stu_g: 4
stu_h: 8
stu_f: 24
address of g: 0x7fffd63a95d0  // struct variable - address dividable by 16,
address of h: 0x7fffd63a95e0  // struct variable - address dividable by 16,
address of f1: 0x7fffd63a95f0 // struct variable - address dividable by 16,
address of f2: 0x7fffd63a9610 // struct variable - address dividable by 16,
address of x: 0x7fffd63a95dc  // non-struct variable - resides within the empty space between struct variable g & h.
address of y: 0x7fffd63a95e8  // non-struct variable - resides within the empty space between struct variable h & f1.
space between g and h: 16
space between h and f1: 16
space between f1 and f2: 32
space between x and f2: -52
space between g and x: 12
space between x and y: 12
space between h and y: 8

ดังนั้นที่อยู่เริ่มต้นสำหรับแต่ละตัวแปรคือ g: d0 x: dc h: e0 y: e8

ป้อนคำอธิบายรูปภาพที่นี่


4
"กฎ" ทำให้มันชัดเจนจริงๆฉันไม่สามารถหากฎที่ตรงไปตรงมาได้ทุกที่ ขอบคุณ
Pervez Alam

2
@PervezAlam หนังสือ<The Lost Art of C Structure Packing>อธิบายกฎค่อนข้างดีแม้จะคิดว่ามันยาวกว่าคำตอบนี้เล็กน้อย หนังสือเล่มนี้มีให้บริการออนไลน์อย่างอิสระ: catb.org/esr/structure-packing
Eric Wang

ฉันจะลองดู แต่มัน จำกัด เฉพาะโครงสร้างการบรรจุหรือไม่ แค่อยากรู้อยากเห็นเพราะฉันชอบคำอธิบายในหนังสือ
ห้องน้ำ

1
@PervezAlam มันเป็นหนังสือที่สั้นมากส่วนใหญ่มุ่งเน้นไปที่เทคโนโลยีที่จะลดรอยความทรงจำของโปรแกรม c มันใช้เวลาเพียงไม่กี่วันในการอ่านจนจบ
Eric Wang

1
@ValidusOculus ใช่มันหมายถึงการจัดตำแหน่ง 16 ไบต์
Eric Wang

44

ฉันรู้ว่าคำถามนี้เก่าและคำตอบส่วนใหญ่ที่นี่อธิบายถึงการขยายตัวได้ดีจริงๆ แต่ในขณะที่พยายามที่จะเข้าใจด้วยตนเองฉันคิดว่ามีภาพ "ภาพ" ของสิ่งที่เกิดขึ้นช่วย

หน่วยประมวลผลอ่านหน่วยความจำใน "ชิ้น" ขนาดที่แน่นอน (คำ) สมมติว่าคำโปรเซสเซอร์มีความยาว 8 ไบต์ มันจะดูที่หน่วยความจำว่าเป็นแถวขนาดใหญ่ 8 หน่วยการสร้างไบต์ ทุกครั้งที่ต้องการรับข้อมูลบางอย่างจากหน่วยความจำมันจะไปถึงหนึ่งในบล็อกเหล่านั้นและรับมัน

การจัดตำแหน่งตัวแปร

ดังที่เห็นในภาพด้านบนไม่สำคัญว่า Char (ความยาว 1 ไบต์) จะอยู่ในช่วงใดช่วงหนึ่งของบล็อกเหล่านั้นทำให้ CPU ต้องประมวลผลเพียง 1 คำเท่านั้น

เมื่อเราจัดการกับข้อมูลที่มีขนาดใหญ่กว่าหนึ่งไบต์เช่น 4 ไบต์ int หรือ 8 ไบต์คู่วิธีที่พวกเขาจัดตำแหน่งในหน่วยความจำสร้างความแตกต่างกับจำนวนคำที่จะต้องประมวลผลโดย CPU หากชิ้นส่วนขนาด 4 ไบต์ถูกจัดเรียงในลักษณะที่พวกเขามักจะพอดีกับด้านในของบล็อก (ที่อยู่หน่วยความจำเป็นหลาย ๆ 4) จะต้องประมวลผลคำเดียวเท่านั้น มิฉะนั้นชุดข้อมูลขนาด 4 ไบต์อาจมีส่วนหนึ่งของตัวเองในบล็อกหนึ่งและอีกส่วนหนึ่งกำหนดให้ตัวประมวลผลประมวลผล 2 คำเพื่ออ่านข้อมูลนี้

เช่นเดียวกับคู่ 8 ไบต์ยกเว้นตอนนี้จะต้องอยู่ในที่อยู่หน่วยความจำหลาย 8 เพื่อรับประกันว่ามันจะอยู่ในบล็อก

สิ่งนี้พิจารณาตัวประมวลผลคำขนาด 8 ไบต์ แต่แนวคิดนี้ใช้กับคำอื่น ๆ

ช่องว่างภายในทำงานโดยการเติมช่องว่างระหว่างข้อมูลเหล่านั้นเพื่อให้แน่ใจว่าสอดคล้องกับบล็อกเหล่านั้นดังนั้นจึงปรับปรุงประสิทธิภาพในขณะที่อ่านหน่วยความจำ

อย่างไรก็ตามตามที่ระบุไว้ในคำตอบของผู้อื่นบางครั้งพื้นที่มีความสำคัญมากกว่าประสิทธิภาพของตัวเอง บางทีคุณกำลังประมวลผลข้อมูลจำนวนมากบนคอมพิวเตอร์ที่ไม่มี RAM (สามารถใช้พื้นที่สลับได้ แต่จะช้ากว่ามาก) คุณสามารถจัดเรียงตัวแปรในโปรแกรมจนกว่าจะมีการเติมน้อยที่สุด (เนื่องจากเป็นแบบสุดขั้วในคำตอบอื่น ๆ ) แต่ถ้านั่นไม่เพียงพอคุณสามารถปิดการใช้งานการแพ็ดอย่างชัดเจนซึ่งเป็นสิ่งที่บรรจุเป็น


3
นี่ไม่ได้อธิบายการจัดเรียงโครงสร้าง แต่มันแสดงให้เห็นถึงการจัดตำแหน่งคำของ CPU ค่อนข้างดี
David Foerster

คุณวาดภาพนั้นด้วยสีหรือไม่? :-)
Ciro Santilli 郝海东冠状病六四事件法轮功

1
@ CiroSantilli709 大 was 六四事件法轮功มันเป็นเรื่องตลก แต่ฉันคิดว่าฉันได้ช่วยประหยัดเวลาในการทำสีแม้ว่า haha
IanC

1
ดียิ่งขึ้นตั้งแต่โอเพ่นซอร์ส (Y)
Ciro Santilli 郝海东冠状病六四事件法轮功

21

โครงสร้างการบรรจุยับยั้งการขยายโครงสร้างการบุรองใช้เมื่อการจัดตำแหน่งสำคัญที่สุดการบรรจุที่ใช้เมื่อพื้นที่สำคัญที่สุด

คอมไพเลอร์บางตัวเตรียมที่#pragmaจะระงับการแพ็ดดิ้งหรือเพื่อให้มันบรรจุจำนวน n ไบต์ บางคนให้คำสำคัญในการทำเช่นนี้ โดยทั่วไปแล้ว pragma ซึ่งใช้สำหรับการแก้ไขการขยายโครงสร้างจะอยู่ในรูปแบบด้านล่าง (ขึ้นอยู่กับคอมไพเลอร์):

#pragma pack(n)

ตัวอย่างเช่น ARM จัดเตรียม__packedคำสำคัญเพื่อระงับการขยายโครงสร้าง อ่านคู่มือผู้แปลเพื่อเรียนรู้เพิ่มเติมเกี่ยวกับสิ่งนี้

โครงสร้างที่อัดแน่นจึงเป็นโครงสร้างที่ไม่มีช่องว่างภายใน

โดยทั่วไปจะใช้โครงสร้างที่อัดแน่น

  • เพื่อประหยัดพื้นที่

  • เพื่อจัดรูปแบบโครงสร้างข้อมูลเพื่อส่งผ่านเครือข่ายโดยใช้โปรโตคอลบางตัว (นี่ไม่ใช่วิธีปฏิบัติที่ดีเพราะคุณต้อง
    จัดการกับ endianness)


5

การเติมและการบรรจุเป็นเพียงสองด้านของสิ่งเดียวกัน:

  • การบรรจุหรือการจัดตำแหน่งคือขนาดที่สมาชิกแต่ละคนถูกปัดเศษ
  • padding เป็นพื้นที่พิเศษที่เพิ่มเข้ามาเพื่อให้ตรงกับการจัดตำแหน่ง

ในmystruct_Aสมมติว่าการจัดตำแหน่งเริ่มต้นที่ 4 แต่ละสมาชิกจะถูกจัดตำแหน่งในหลายไบต์ 4 เนื่องจากขนาดเท่ากับchar1 การ padding สำหรับaและcคือ 4 - 1 = 3 ไบต์ในขณะที่ไม่จำเป็นต้องใช้การขยายint bซึ่งมีขนาด 4 ไบต์อยู่แล้ว mystruct_Bมันทำงานในลักษณะเดียวกันสำหรับ


1

การจัดโครงสร้างจะทำก็ต่อเมื่อคุณบอกคอมไพเลอร์ของคุณอย่างชัดเจนเพื่อแพ็คโครงสร้าง การขยายคือสิ่งที่คุณเห็น ระบบ 32- บิตของคุณกำลังขยายแต่ละฟิลด์เพื่อจัดเรียงคำ ถ้าคุณบอกคอมไพเลอร์ให้แพ็คโครงสร้างพวกมันจะเป็น 6 และ 5 ไบต์ตามลำดับ อย่าทำอย่างนั้น มันไม่ได้พกพาได้และทำให้คอมไพเลอร์สร้างโค้ดได้ช้ากว่ามาก (และบางครั้งก็เป็นบั๊กซี)


1

ไม่มีข้อสงสัยเกี่ยวกับมัน! ผู้ที่ต้องการเข้าใจเรื่องจะต้องทำสิ่งต่อไปนี้


1

กฎสำหรับการขยาย:

  1. สมาชิกของโครงสร้างทุกคนควรอยู่ที่ที่อยู่หารด้วยขนาดของมัน Padding ถูกแทรกระหว่างองค์ประกอบหรือที่ส่วนท้ายของโครงสร้างเพื่อให้แน่ใจว่าเป็นไปตามกฎนี้ สิ่งนี้ทำเพื่อการเข้าถึงบัสที่ง่ายขึ้นและมีประสิทธิภาพยิ่งขึ้นโดยฮาร์ดแวร์
  2. การขยายส่วนท้ายของโครงสร้างจะตัดสินใจตามขนาดของสมาชิกที่ใหญ่ที่สุดของโครงสร้าง

ทำไมต้องกฎ 2: พิจารณาโครงสร้างต่อไปนี้

โครงสร้าง 1

หากเราต้องสร้างอาร์เรย์ (จาก 2 structs) ของโครงสร้างนี้จะไม่ต้องใช้การขยายภายในตอนท้าย:

อาร์เรย์ Struct1

ดังนั้นขนาดของ struct = 8 ไบต์

สมมติว่าเราต้องสร้าง struct อื่นดังนี้

โครงสร้าง 2

ถ้าเราต้องสร้างอาร์เรย์ของ struct นี้มีความเป็นไปได้ 2 อย่างคือจำนวนไบต์ของการเติมที่จำเป็นในตอนท้าย

A. ถ้าเราเพิ่ม 3 ไบต์ที่ท้ายและจัดให้เป็น int และไม่ยาว:

อาร์เรย์ Struct2 จัดชิดกับ int

B. ถ้าเราเพิ่ม 7 ไบต์ที่ส่วนท้ายและจัดแนวเป็น Long:

อาร์เรย์ Struct2 จัดแนวเป็น Long

ที่อยู่เริ่มต้นของอาเรย์ที่สองคือผลคูณของ 8 (เช่น 24) ขนาดของ struct = 24 ไบต์

ดังนั้นโดยการจัดที่อยู่เริ่มต้นของอาเรย์ถัดไปของโครงสร้างให้กับสมาชิกที่ใหญ่ที่สุดจำนวนมาก (เช่นถ้าเราต้องสร้างอาเรย์ของโครงสร้างนี้ที่อยู่แรกของอาเรย์ที่สองจะต้องเริ่มต้นที่ที่อยู่ซึ่งเป็นหลาย ของสมาชิกที่ใหญ่ที่สุดของ struct ที่นี่เป็น 24 (3 * 8)) เราสามารถคำนวณจำนวนไบต์ padding ที่ต้องการในตอนท้าย


-1

การจัดตำแหน่งโครงสร้างข้อมูลเป็นวิธีการจัดเรียงและเข้าถึงข้อมูลในหน่วยความจำคอมพิวเตอร์ ประกอบด้วยสองแยกประเด็น แต่ที่เกี่ยวข้องกับการจัดเรียงข้อมูลและโครงสร้างข้อมูล padding เมื่อคอมพิวเตอร์สมัยใหม่อ่านจากหรือเขียนไปยังที่อยู่หน่วยความจำมันจะทำสิ่งนี้ในชิ้นคำขนาด (เช่น 4 ไบต์ชิ้นบนระบบ 32 บิต) หรือใหญ่กว่า การจัดตำแหน่งข้อมูลหมายถึงการวางข้อมูลที่ที่อยู่หน่วยความจำเท่ากับขนาดของคำบางคำซึ่งเพิ่มประสิทธิภาพของระบบเนื่องจากวิธีที่ CPU จัดการกับหน่วยความจำ เมื่อต้องการจัดแนวข้อมูลคุณอาจจำเป็นต้องแทรกไบต์ที่ไม่มีความหมายบางอย่างระหว่างจุดสิ้นสุดของโครงสร้างข้อมูลล่าสุดและจุดเริ่มต้นของถัดไปซึ่งเป็นการขยายโครงสร้างข้อมูล

  1. เพื่อจัดตำแหน่งข้อมูลในหน่วยความจำหนึ่งไบต์หรือมากกว่านั้นว่างเปล่า (ที่อยู่) จะถูกแทรก (หรือปล่อยว่าง) ระหว่างที่อยู่หน่วยความจำที่ถูกจัดสรรสำหรับสมาชิกโครงสร้างอื่น ๆ ในขณะที่การจัดสรรหน่วยความจำ แนวคิดนี้เรียกว่าการเสริมโครงสร้าง
  2. สถาปัตยกรรมของตัวประมวลผลคอมพิวเตอร์เป็นวิธีที่สามารถอ่าน 1 คำ (4 ไบต์ในตัวประมวลผล 32 บิต) จากหน่วยความจำในแต่ละครั้ง
  3. ในการใช้ประโยชน์จากโปรเซสเซอร์นี้ข้อมูลจะถูกจัดเป็น 4 แพ็คเกจเสมอซึ่งจะนำไปสู่การแทรกที่อยู่ที่ว่างระหว่างที่อยู่ของสมาชิกรายอื่น
  4. เนื่องจากโครงสร้างการขยายความในโครงสร้างใน C ขนาดของโครงสร้างจึงไม่เหมือนกับสิ่งที่เราคิด

1
ทำไมคุณต้องเชื่อมโยงไปยังบทความเดียวกัน5 ครั้งในคำตอบของคุณ? โปรดเก็บลิงก์เดียวไว้ในตัวอย่าง นอกจากนี้เนื่องจากคุณเชื่อมโยงไปยังบทความของคุณคุณต้องเปิดเผยข้อเท็จจริงนั้น
Artjom B.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.