Masalah Penyelarasan Kelas

Saya sedang menguji penyelarasan kelas dan menemukan perilaku aneh. Saya mengujinya dengan pengaturan kompiler VS2012 pengaturan penyelarasan 4 dan 8 byte tetapi dalam setiap kasus hasilnya sama.

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;

Setiap kali keluarannya adalah:

Sizeof(Alignemnt)   : 4

Sizeof(Alignemnt_1) : 8

Sizeof(Alignemnt_2) : 12

Menurut saya, ukuran Alignemnt_2 harus 16 byte.


person CrazyC    schedule 29.01.2015    source sumber
comment
Jadi, apa pertanyaanmu? Menurut saya kompilernya baik-baik saja?   -  person gha.st    schedule 29.01.2015
comment
Menurut saya, ukuran Alignemnt_2 harus 16 byte.   -  person CrazyC    schedule 29.01.2015
comment
int biasanya berukuran 4 byte. char[2] hanya objek 2 byte. Anda mendapatkan ukuran 12 byte karena int pertama membutuhkan 4 byte, objek kedua membutuhkan 2 byte, dan objek ketiga harus sejajar dengan 4 byte.   -  person Charlie    schedule 29.01.2015
comment
@TonyD Ukuran adalah kelipatan penyelarasan, oleh karena itu penyelarasan mempengaruhi ukuran. Dan ini bahkan belum membicarakan tentang apa yang dilakukan perataan anggota terhadap ukuran objek yang memuatnya.   -  person gha.st    schedule 29.01.2015
comment
Mungkin dia harus mencoba mengkompilasi lebih banyak tes! Setelah membaca sedikit, saya berpikir, mungkin kompiler Visual Studio mengoptimalkan penyimpanan data dengan cara khusus?   -  person Cinch    schedule 29.01.2015
comment
Saya tersadar bahwa saya tidak tahu pengaturan apa yang Anda gunakan atau bagaimana pengaturan tersebut dimainkan antar objek, vs anggota struct. Jika anggota struct harus selaras 8 byte, maka #2 harus 24 byte (atau 20 byte), tetapi jika penyelarasan berada pada tingkat alokasi objek/memori, maka itu tidak mengubah ukuran Anda struct sama sekali.   -  person Charlie    schedule 29.01.2015
comment
Sedikit offtop: Anda dapat menggunakan struct daripada class untuk alasan pengujian guna menghemat waktu Anda dengan menghindari pencetakan kata kunci public   -  person borisbn    schedule 29.01.2015


Jawaban (3)


Saya berasumsi Anda mengacu pada sakelar /Zp, yang memungkinkan Anda mengontrol Penyelarasan anggota struktur maksimum:

Saat Anda menentukan opsi ini, setiap anggota struktur setelah yang pertama disimpan pada ukuran tipe anggota atau batas n-byte (di mana n adalah 1, 2, 4, 8, atau 16), mana saja yang lebih kecil.

Karena Anda tidak menggunakan anggota struct dengan penyelarasan lebih dari 4 byte (sizeof(int) dan alignof(int) keduanya 4), semua pengaturan 4 byte ke atas akan menghasilkan perilaku yang persis sama.

Jika Anda ingin menentukan perataan tepat anggota struktur, pertimbangkan untuk menggunakan standar C++ alignas yang memungkinkan Anda menentukan perataan persis yang seharusnya dimiliki seorang anggota (VS 2012 harus mendukungnya iirc).

Lihat hasil penggunaan alignas.

person gha.st    schedule 29.01.2015

Penyelarasan tidak boleh mengubah ukuran objek Anda, hanya alamat awal objek. Misalnya, objek sejajar 8 byte bisa berada di alamat 0x100000 atau 0x100008, atau alamat apa pun yang diakhiri dengan 0 atau 8 bila ditulis dalam hex tetapi tidak 0x100004.

person Charlie    schedule 29.01.2015
comment
Saya tidak menyetujuinya. keselarasan terkait dengan padding yang mengubah ukuran objek. - person CrazyC; 29.01.2015
comment
Selain itu, ukuran objek akan menjadi kelipatan dari perataannya. - person gha.st; 29.01.2015
comment
Ya. @gha..st. Penyelarasan selalu menghasilkan ukuran objek kelipatan dari pengaturan. Di sini saya membuatnya 8 byte jadi bukannya 12 seharusnya 16. - person CrazyC; 29.01.2015
comment
Ukurannya tidak dipengaruhi oleh penyelarasan. Efisiensi pengepakan dipengaruhi oleh penyelarasan, namun byte yang diperlukan untuk menyimpan objek tidak. Misalnya, jika saya mengemas objek yang perlu disejajarkan 8 byte di sebelah sesuatu yang tidak peduli, tidak perlu ada padding. - person Charlie; 29.01.2015
comment
@Charlie Kecuali Anda berbicara tentang tipe yang disejajarkan, lihat contoh ini yang melakukan hal itu: Kemas dan Objek yang disejajarkan dan berukuran 8 byte di samping objek dengan penyelarasan dan ukuran 1 byte. Ukurannya berubah dari 9 byte menjadi 16 byte saat mengubah perataan anggota pertama. - person gha.st; 29.01.2015
comment
@ gha.st Saya sedang memikirkan sesuatu tentang apakah penyelarasan berlaku pada tingkat struct atau (yaitu struct dapat disejajarkan 8 byte, tetapi penyelarasan tidak mengikuti anggota) vs penyelarasan anggota - penyelarasan diterapkan ke level struct vs alignas diterapkan ke setiap elemen. - person Charlie; 29.01.2015

No.

Penjajaran 2 baik-baik saja.

Anda memiliki 2 karakter bersebelahan, itu berarti Anda memiliki 2 dari 4 byte yang digunakan. Pengepakan akan menyelaraskannya menjadi 4 byte, dan Anda akan mendapatkan 4 + 4 +4 .

Jika Anda ingin berakhir hingga 16 Anda dapat mencoba deklarasi berikut:

 {
      char a;
      int b;
      char c;
      int d;
 }
person MichaelCMS    schedule 29.01.2015
comment
@CrazyC Ada alasan untuk downvote? Apakah ada yang saya nyatakan tidak benar? atau Anda hanya suka downvoting demi downvoting? - person MichaelCMS; 29.01.2015
comment
@CrazyC ah, maaf. Saya pikir Anda memberi suara negatif. Namun, saya masih ingin tahu mengapa downvoter memberikan suara negatif ... - person MichaelCMS; 29.01.2015