1. 程式人生 > >【理論實踐】用alignas代替#pragma pack

【理論實踐】用alignas代替#pragma pack

知識背景:

       欄位對齊,使物件或成員的地址滿足一定要求。4位元組對齊就是地址都是4的整數倍,這個必須是2的N次方。

       為什麼要對齊?一方面,如果4位元組對齊了,對於128個記憶體空間,實際只有32個獨立地址,相當於管理地址變少了,檔案系統經常這麼用,用少的定址空間,管理更大的磁碟空間。另一方面,一些硬體設計上了,為了一些考慮,強制要求地址要符合指定規則。

       對齊有什麼影響?最直接的影響就是佔用內在大小變了,會影響sizeof,舉例如下:

struct A
{
       int a;
       char b;
       int c;
};
        sizeof(A)大小並不是4+1+4=9,而是12,4+4+4。

        為什麼要改變對齊?強轉之下,受對齊影響,不正確了。容易遇到的場景就是:收到網路位元組流,訊息頭是結構化的,定義一個結構體,強轉讀取對應的欄位

       怎麼更改對齊大小?

       c++11之前,我們經常這麼用

       #pragma pack(push)   //儲存當前的對齊方式
       #pragma pack(1)         //指定接下來,1位元組對齊
       //定義你的結構體
       #pragma pop(pop)       //指定恢復儲存的對齊方式

        明顯這個相當暴力了,如果每個人都這麼做,至少3行程式碼。為了省事,總容易有人不push和pop,直接改,某人就會在不知情的情況下,包含了這個標頭檔案,進而受影響……

        於是,編譯器突破規範,定義了擴充套件:__declspec(align(n))等,記住,是等,也就是各做各的,不統一,於是c++11火速規範化制定了這個標準:alignas 和alignof。

        a開頭的關鍵字,排在最前面,有人會鬱悶吧,總看到,卻不知道是什麼,我從誤區開始,逐步解釋一下。

        用法:alignas(t)  define;   t可以是個常量表達式,也可以是具體的大小,也可以是一個型別。 define是原本的定義語句,例如:

        alignas(int) int b;

        struct alignas(33) s

        {

                int a;

        };

        alignof(type),和sizeof非常類似,只是返回對應型別的對齊大小,例如:

         cout << alignof(s);           //返回s的對齊方式

         cout << alignof(s::a) ;      //返回s成員的對齊方式

理論實踐

        知識講完了,開始錯誤之路吧

        一、對齊不是2的N次方

struct alignas(3) A    //error: requested alignment is not a power of 2
{
        char a;
        char b;
        char c;
        char d;
};

        二、理解錯了對齊物件

struct alignas(2) A
{
        char a;
        char b;
        char c;
        char d;
};
if(sizeof(A) == 8)
       alignas修飾結構體時,不是對齊結構體每個成員,而是對齊結構體本身,所以大小不是4*2=8,則是4不變。如果再增加一個char成員,則大小6, 不是5。

       這樣去理解結構體對齊:A對齊了,A+sizeof(A)是下一個A元素的地址,需要同樣滿足對齊,所以需要補空間1。

        三、對齊低於結構體成員最大對齊

struct alignas(2) A
{
        int a;
        char b;
};
        sizeof(A)不是6,而是8,因為a已經是4對齊了,所以b之後會補到8。   alignas(16)則大小是16。

         四、分析一下複雜的,就畢業了,sizeof(B)是多少?128

struct alignas(32) A
{
        int a;
        alignas(8) char b;
};

struct B
{
        A a;
        A b;
        alignas(1) char c;
        A d;
};
          

          以後,再懷疑位元組對齊時,請用alignof輸出實際的對齊方式看看,不用再去列印記憶體或除錯了。

相關推薦

理論實踐alignas代替#pragma pack

知識背景:        欄位對齊,使物件或成員的地址滿足一定要求。4位元組對齊就是地址都是4的整數倍,這個必須是2的N次方。        為什麼要對齊?一方面,如果4位元組對齊了,對於128個記憶體空間,實際只有32個獨立地址,相當於管理地址變少了,檔案系統經常這麼用,

理論實踐new的三種用法:plain new,nothrow new和placement new

一、plain new就是最普通的new的,動態建立一個物件或陣列,基本用法如下: class A { int m_v; public: A() {} A(int v) : m_v(v) {} A(doub

機器學習實踐Python實現樸素貝葉斯分類器

       閱讀學習了《機器學習》第7章的貝葉斯分類器後,為了加深理解和加強python的程式碼能力,因此嘗試使用Python實現樸素貝葉斯分類器,由於初學Python的緣故,程式碼的一些實現方法可能比較繁瑣,可閱讀性有待提高。程式碼如下: #import numpy a

實踐路由為webApp單頁應用提供多入口

前言 我1個月前開發的webApp是個單入口的單頁應用,那個時候需求沒有很複雜,僅僅是一個購物的站點,但後來不停地新增功能,而且近期還提出需要把webAPP的部分頁面分享到 IOS webView、微信朋友圈,並且能完成完整的業務邏輯。 我的策略

專案實踐依賴注入得好,設計模式隨便搞

![首圖.png](https://img2020.cnblogs.com/blog/1496775/202101/1496775-20210121092446395-1811059139.jpg) > 以專案驅動學習,以實踐檢驗真知 # 前言 設計模式是我們程式設計道路上繞不開的一環,用好了設計模式能

第一組例文檔,功能說明書,技術說明書

正在 分鐘 委托 reading 簡單 觸發 作業 聲音 暫時 場景:用戶使用自習助手 1.背景: (1)典型用戶:正在上自習的東北大學學生 (2)用戶的需求/迫切解決的問題:用戶在上自習時如何專心學習 (3)假設:用戶正確安裝本軟件 2.場景:關於這個場景的文字描述

第二組例文檔+功能說明書+技術說明書

str password 點擊事件 註冊界面 ext 漸變 pass tdi 能說 標題一:用戶註冊後進入遊戲主頁面 角色:首次使用Hunter的用戶 主要成功場景: 用戶點擊註冊; 用戶在用戶名文本框中輸入用戶名 用戶在密碼文本框中輸入密碼 用戶在確認密碼文本框中再一次

C/C++:C實現輸出日期的陰歷日子

print http this while lunar void 大小 oid pan 前言 輸出陰歷一直是個老大難的問題。由於陰歷日子沒有規律。所以這裏須要做的就是通過打表的算法做到輸出陰歷日子,可是非常多人都不太了解原理,我這裏就給大家送上了一個福

Web前端CSS3實現彈幕

font ram hover 字符 才會 命令 .sh left window 初版 用css3來實現彈幕確實比較簡單,只需要設置動畫讓彈幕從屏幕右側移動到屏幕左側即可,一開始是這樣實現的 .danmu { position: fixed; left: 100%

js 實踐js 實現木桶布局

cto enter 最後一行 scrip fine inner get code 兩個 還有兩個月左右就要準備實習了,所以特意練一練,今天終於搞定了js 的木桶布局了 這一個是按照一個插件的規格去寫的以防以後工作需要,詳細的解釋在前端網這裏 http://www.qdfun

Chapter 3戶體驗分析

image blog 評論 gin 自己 img 結束 基於 margin   在我們日常生活中,微信公眾號的普遍性已經是達到90%以上,如何做好一個微信公眾號對於一個組織來說是非常重要的。因為公眾號起到的作用是【宣傳信息】,如何讓一些商家想讓用戶了解的信息及時傳達或者讓用

小程序nginx進行反向代理處理(windows)

TP 代理 targe 反向 todo nginx安裝 http cnblogs smi 在通過json-server搭建本地服務器得到 http://localhost:3000/todos 的基礎上,要想將接口改為www.test.com/todos這樣的形式 ,

python基礎字典做一個小型的查詢數據庫

import oot 字符 odin 參數錯誤 err 輸出 put 異常 例子來源於《python基礎教程》第三版,57p 該例子主要是使用字典的方式,實現一個小型的數據庫,通過查詢字典的鍵值來獲取用戶的信息。 本人修改了部分代碼。 #!/usr/bin/python3

工程實踐服務器數據解析

something 時間比較 數據訪問 shu 成員 字段值 ear 計時 日誌 本文來自網易雲社區作者:孫建順在客戶端開發過程中一個重點內容就是解析服務器數據,關於這個話題也許大家首先會去思考的問題是用哪個json解析庫。是的,目前通過json格式進行數據傳輸是主流的方式

ERC1155實踐歐陽詢書法復制品從確權設計到買賣測試

ply string doc gpu 構建 eas fontsize tab urn 作者介紹 筆名輝哥 副總(賦能中心)尖晶投資 1,摘要 【本文目標】通過本文學習,了解以太坊ERC1155標準規範和ERC1155Mintable可增發智能合約函數功能,並通過一個有趣的

取證分析linux命令xxd來獲取dump檔案資訊獲得flag

題目連結:https://blog.csdn.net/xiangshangbashaonian/article/details/82747394 拿到一道CTF題目  notepad++開啟如下所示 [email protected]:~/Desktop$ fi

很有趣Python實現一個簡單的人臉識別,原來我和這個明星如此相似

近幾年來,興起了一股人工智慧熱潮,讓人們見到了AI的能力和強大,比如影象識別,語音識別,機器翻譯,無人駕駛等等。總體來說,AI的門檻還是比較高,不僅要學會使用框架實現,更重要的是,需要有一定的數學基礎,如線性代數,矩陣,微積分等。 幸慶的是,國內外許多大神都已經給我們造好“輪子”,我們可

Python實戰Scrapyd把Scrapy爬蟲一步一步部署到騰訊雲

將我們的爬蟲部署到騰訊雲伺服器上面。廢話不多說,我們就來實戰操作吧。 這裡選擇什麼雲服務都是可以的,阿里雲,AWS,騰訊雲,其他雲都是沒有問題的。部署方法基本一樣,這裡為了方便,所以筆者選擇了騰訊雲來做講解。 既然我們選擇了騰訊雲,首先去騰訊雲的官網,註冊登入一下。 點選複製https:

c語言迴圈結構輸出下列數字金字塔

  #include<stdio.h> void main(){ int i,j,k; for(i=1;i<=10;i++){ for(j=10;j>i;j--) printf(" "); for(k=1;k<=(2*i-1)/2

GDAL學習GDAL讀取柵格資料

1.根據座標讀取遙感影像的單個畫素值 # week 4: get pixel values at a set of coordinates by reading in one pixel at a time import os, sys, time from osgeo import gdal