溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++中結構體對齊規則的示例分析

發布時間:2021-08-17 08:57:14 來源:億速云 閱讀:228 作者:小新 欄目:開發技術

這篇文章主要介紹了C++中結構體對齊規則的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

基本概念

CPU一次能讀取多少個字節的數據主要是看數據總線是多少位的,16位CPU一次能讀取2個字節,32位CPU一次能讀取4個字節,64位CPU一次能讀取8個字節。并且不能跨內存區間訪問,這句話的意思可以理解為,如果CPU是32位的話,那么可以將整個內存區間每4個字節分為一塊(BLOCK),每次讀取一個BLOCK的數據。

那么對于下面這個結構體:

struct st {
    char c;
    int i;
};

如果不進行對齊操作,char 的地址范圍0x00000000,int的地址范圍為0x00000001----0x00000004,int分布在兩個不同的BLOCK上,因此要讀取int需要兩次操作;如果進行4字節對齊,那么int的地址范圍為0x00000004----0x00000007,處在一個BLOCK上,因此只需一次讀取操作即可。缺點也顯而易見,多占用了3個字節。這也是典型的一種空間換時間的方法吧。

結構體對齊的規則

結構體對齊需要滿足以下三條規則,其中系統對齊模數在64位機器上默認為8字節,32位機器上默認為4字節。通過預處理指令#pargma pack(N)可以修改系統模數為N個字節。

1、以結構體第一個元素的地址為起始地址,亦即結構體的起始地址。由上可知,第一個元素的偏移量為0;

2、結構體元素對齊原則:結構體成員的對齊模數為類型大小與系統對齊模數的較小者;結構體成員的偏移量(填充)為對齊模數的整數倍。

3、結構體大小對齊原則:結構體的對齊模數為結構體最大元素與系統對齊模數的較小者;結構體的大?。ㄌ畛洌榻Y構體對齊模數的整數倍。

程序驗證

測試環境為64位Windows ,VS2019,定義結構體st1,包含3個元素char,int,double,定義系統對齊模數為4個字節。

#include <iostream>

#pragma pack(4)

using Tsize = unsigned long long;
using namespace std;

struct st1 {
    char c;
    int i;
    double db;
    Tsize ch_offset() {
        return Tsize((Tsize)&this->c - (Tsize)this);
    }
    Tsize int_offset() {
        return Tsize((Tsize)&this->i - (Tsize)this);
    }
    Tsize double_offset() {
        return Tsize((Tsize)&this->db - (Tsize)this);
    }
};

int main() {
    cout << "st1結構體大小" << sizeof(st1) << endl;
    cout << "char 偏移量=" << st1().ch_offset() << endl;
    cout << "int偏移量=" << st1().int_offset() << endl;
    cout << "double偏移量=" << st1().double_offset() << endl;
    return 0;
}

首先我們按照對齊規則來進行分析。第一個元素為char,類型大小為1個字節,對齊模數min(1,4)=1,偏移量為0是對齊模數的整數倍,無需填充(從這里我們可以看到,第一個字節偏移量始終為0,是不需要填充的),下一個元素的偏移從1開始;第二個元素為int,類型大小4個字節,對齊模數為4個字節,不填充時偏移量為1,不是4的整數倍,因此這里需要填充3個字節,使得int的偏移量為4,且下一個元素偏移從8開始;第三個元素是double,類型大小為8個字節,對齊模數為4,偏移量從8開始,是4的整數倍,因此無需填充,占用8個字節,因此結構體的大小為16個字節。運行程序輸出:

C++中結構體對齊規則的示例分析

將系統對齊模數修改為1 【#pargma pack(1)】,這樣的話,任何情況下都無需填充(不足一個字節的類型視為一個字節),結構體的大小即為結構體元素大小之和。運行程序輸出:

C++中結構體對齊規則的示例分析

將系統對齊模數修改為8 【#pargma pack(8)】,這樣的話,任何情況下都無需填充(不足一個字節的類型視為一個字節),結構體的大小即為結構體元素大小之和。運行程序輸出:

C++中結構體對齊規則的示例分析

Emmm,好像和系統對齊模數為4時沒什么變化。那我們將int 和 double的順序換一下呢?

#include <iostream>

#pragma pack(8)

using Tsize = unsigned long long;
using namespace std;

struct st1 {
    char c;
    double db;
    int i;
    Tsize ch_offset() {
        return Tsize((Tsize)&this->c - (Tsize)this);
    }
    Tsize int_offset() {
        return Tsize((Tsize)&this->i - (Tsize)this);
    }
    Tsize double_offset() {
        return Tsize((Tsize)&this->db - (Tsize)this);
    }
};

int main() {
    cout << "st1結構體大小" << sizeof(st1) << endl;
    cout << "char 偏移量=" << st1().ch_offset() << endl;
    cout << "double偏移量=" << st1().double_offset() << endl;
    cout << "int偏移量=" << st1().int_offset() << endl;
    return 0;
}

C++中結構體對齊規則的示例分析

順序調了下,結構體就比原來大了8個字節!!!從中我們可以看出,將結構體元素從小到大排列,可以最大程度節省空間。

感謝你能夠認真閱讀完這篇文章,希望小編分享的“C++中結構體對齊規則的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

c++
AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女