之前寫了這樣一段**,
printf("%d | %d \n", sizeof(std::list), sizeof(std::list));
/*24 | 24
*/
首先我們需要知道list是個什麼東東:
點進std::list
,可以看到以下**,可以看出list這玩意貌似沒有成員?但他繼承了乙個 __list_imp<_tp, _alloc>:
template */>
class _libcpp_template_vis list
: private __list_imp<_tp, _alloc>
點進__list_imp可以看到這個**,有乙個__end_,我們離真相又近了一點了,__end_是__node_base型別的,可以看到前邊有個typedef:
template class __list_imp
點進__list_node_base,看看這是個啥玩意。哦豁,發現了兩個指標!
struct __list_node_base
;
注意,這是個父結構體,再看看他子結構體的實現,如下:
template struct __list_node
: public __list_node_base<_tp, _voidptr>
};
好啊,終於找到了list的資料成員了,兩根指標,乙個資料,類似於以下形式:
templatestruct test
但是回到正題,為什麼std::list
是24呢?
我的機子是64位機,指標是8bytes,int是4個位元組,8*2+4 = 20,沒毛病,20。
但是輸出為什麼是24呢?
遇到這種問題,我們一般就需要從編譯器角度考慮了(首先可以肯定,這肯定不是我的問題!)
結構體對齊,嗯結構體對齊,這是編譯器考慮的範疇。
記憶體對齊的作用:
位元組對齊主要是為了提高記憶體的訪問效率,比如intel 32位cpu,每個匯流排週期都是從偶位址開始讀取32位的記憶體資料,如果資料存放位址不是從偶數開始,則可能出現需要兩個匯流排週期才能讀取到想要的資料,因此需要在記憶體中存放資料時進行對齊。結論1:一般情況下,結構體所佔的記憶體大小並非元素本身大小之和。
結論2:結構體記憶體大小應按最大元素大小對齊,如果最大元素大小超過模數,應按模數大小對齊。
這裡的模數就需要編譯器來操作啦!
我們試試取消記憶體對齊試試:
#include templatestruct test __attribute__((__packed__)) ;
int main()
/*4 | 8
24 | 24
20 | 24
*/
可以發現,test
已經是20了,說明list
為24的原因就是因為記憶體對齊所致。
記憶體對齊的相關知識可以參考:
詳細的記憶體對齊內容,將在以後**....
番外1 什麼?sizeof list 竟然是24
之前寫了這樣一段 printf d d n sizeof std list sizeof std list 24 24 首先我們需要知道list是個什麼東東 點進std list,可以看到以下 可以看出list這玩意貌似沒有成員?但他繼承了乙個 list imp tp,alloc template ...
番外 函式隨記
void swap int a,int b a 和 b 列舉四種情況 a 110 0 b 010 1 a 100 1 b 110 0 和最初的 a 一樣 a 010 1 和最初的 b 一樣 data 1 bit num bit num 為0 資料最大位1.function void getsyste...
番外 socketserver用法
是不是被一般寫法,多程序寫法,多執行緒寫法甚至是協程寫法搞的不可開交 雲裡霧裡,彷彿將要放棄 再配上伺服器要服務多個客戶端 完蛋了,全都亂了 那今天就給你推薦乙個好的模組!sockerserver 具體操作 import socketserver 1 引入模組 class myserver sock...