C++中sizeof運算符全面詳解和代碼示例

sizeof 是 C++ 中的一個編譯時運算符,用于獲取對象或類型所占的字節數(以 size_t 返回)。它是掌握底層內存模型、結構體對齊、數組大小計算等的重要工具。


1. 基本語法

sizeof(type)      // 獲取類型的大小
sizeof expression // 獲取表達式結果的大小

2. 返回值類型

  • sizeof 返回類型是 std::size_t(定義在 <cstddef> 中),是一個無符號整型,足以容納系統中對象的最大可能大小。

3. 示例代碼一覽

#include <iostream>
#include <cstddef>int main() {int a = 5;double b = 3.14;int arr[10];std::cout << "sizeof(int): " << sizeof(int) << "\n";std::cout << "sizeof(a): " << sizeof(a) << "\n";std::cout << "sizeof(b): " << sizeof b << "\n";  // 可省略括號std::cout << "sizeof(arr): " << sizeof(arr) << "\n";std::cout << "Number of elements in arr: " << sizeof(arr) / sizeof(arr[0]) << "\n";return 0;
}

4. 結構體對齊示例(含填充字節)

#include <iostream>struct A {char c;     // 1 byteint i;      // 4 bytes
};int main() {std::cout << "sizeof(char): " << sizeof(char) << "\n";std::cout << "sizeof(int): " << sizeof(int) << "\n";std::cout << "sizeof(A): " << sizeof(A) << "\n";  // likely 8 due to padding
}

結構體 A 實際大小常常為 8,而不是 5,這是因為編譯器插入了填充字節以保證成員變量對齊(稱為結構體對齊或 padding)。


5. 指針和數組的區別

int arr[10];
int* p = arr;std::cout << "sizeof(arr): " << sizeof(arr) << "\n";     // 10 * sizeof(int)
std::cout << "sizeof(p): " << sizeof(p) << "\n";         // 指針大小,通常是 8(64 位系統)

6. 類的 sizeof 示例(含虛函數、繼承)

#include <iostream>class Base {virtual void foo() {}
};class Derived : public Base {int data;
};int main() {std::cout << "sizeof(Base): " << sizeof(Base) << "\n";      // 有 vptr,通常為 8std::cout << "sizeof(Derived): " << sizeof(Derived) << "\n"; // vptr + int + padding
}

7. 注意事項

事項說明
sizeof 是編譯時運算除非作用于 VLA(C99 風格,C++ 不支持),否則計算在編譯期完成
對于類型無需括號sizeof expression 中括號可省;sizeof(type) 中必須加括號
數組退化sizeof(arr) 在函數參數中為指針大小,不是數組總大小
對動態分配數組無效sizeof(new int[10]) 得到的是指針大小,不是數組大小

8. sizeof 與模板配合(常用于靜態斷言)

template<typename T>
void check_size() {static_assert(sizeof(T) <= 8, "Type is too big!");
}

9. C++11 起的 alignof

#include <iostream>
#include <type_traits>struct MyStruct {char c;double d;
};int main() {std::cout << "sizeof(MyStruct): " << sizeof(MyStruct) << "\n";std::cout << "alignof(MyStruct): " << alignof(MyStruct) << "\n";
}

10、綜合示例

下面是一個 跨平臺結構體對齊測試工具類 的完整示例,功能如下:

  • 顯示結構體每個成員的偏移量(offsetof);
  • 顯示結構體整體 sizeofalignof
  • 兼容 GCC / Clang / MSVC;
  • 可用于診斷因字節對齊(padding)帶來的內存浪費。

工具類:StructInspector

功能說明:

  • 使用 offsetof 獲取成員偏移;
  • 使用 sizeofalignof 獲取結構體大小和對齊;
  • 可擴展支持任意結構體(通過宏注冊成員)。

示例代碼

#include <iostream>
#include <iomanip>
#include <cstddef>
#include <string>
#include <type_traits>// 通用格式輸出宏
#define PRINT_ALIGN_INFO(T) \std::cout << "Struct: " << #T << "\n" \<< "  Size:    " << sizeof(T) << "\n" \<< "  Alignof: " << alignof(T) << "\n\n";// 檢查偏移宏(成員名必須為字符串形式)
#define PRINT_MEMBER_OFFSET(StructType, Member) \std::cout << std::setw(20) << #Member << " @ offset: " << offsetof(StructType, Member) << "\n";// -----------------------------
// 示例結構體
// -----------------------------
struct MyStruct {char    c1;double  d;int     i;char    c2;
};struct PackedStruct {char c1;char c2;int  i;
} __attribute__((packed));  // GCC/Clang 特性(MSVC: use #pragma pack)#pragma pack(push, 1)
struct MsvcPackedStruct {char c1;char c2;int i;
};
#pragma pack(pop)// -----------------------------
// 工具函數:打印結構體布局
// -----------------------------
template<typename T>
void InspectStructLayout(const std::string& name) {std::cout << "==============================\n";std::cout << "Inspecting: " << name << "\n";std::cout << "sizeof(" << name << ") = " << sizeof(T) << "\n";std::cout << "alignof(" << name << ") = " << alignof(T) << "\n";std::cout << "------------------------------\n";
}// 示例專用模板:打印具體成員偏移
void Inspect_MyStruct() {InspectStructLayout<MyStruct>("MyStruct");PRINT_MEMBER_OFFSET(MyStruct, c1);PRINT_MEMBER_OFFSET(MyStruct, d);PRINT_MEMBER_OFFSET(MyStruct, i);PRINT_MEMBER_OFFSET(MyStruct, c2);std::cout << "\n";
}void Inspect_PackedStruct() {InspectStructLayout<PackedStruct>("PackedStruct");PRINT_MEMBER_OFFSET(PackedStruct, c1);PRINT_MEMBER_OFFSET(PackedStruct, c2);PRINT_MEMBER_OFFSET(PackedStruct, i);std::cout << "\n";
}void Inspect_MsvcPackedStruct() {InspectStructLayout<MsvcPackedStruct>("MsvcPackedStruct");PRINT_MEMBER_OFFSET(MsvcPackedStruct, c1);PRINT_MEMBER_OFFSET(MsvcPackedStruct, c2);PRINT_MEMBER_OFFSET(MsvcPackedStruct, i);std::cout << "\n";
}// -----------------------------
// 主程序入口
// -----------------------------
int main() {Inspect_MyStruct();Inspect_PackedStruct();Inspect_MsvcPackedStruct();return 0;
}

示例輸出(Linux + GCC)

==============================
Inspecting: MyStruct
sizeof(MyStruct) = 24
alignof(MyStruct) = 8
------------------------------c1 @ offset: 0d @ offset: 8i @ offset: 16c2 @ offset: 20==============================
Inspecting: PackedStruct
sizeof(PackedStruct) = 6
alignof(PackedStruct) = 1
------------------------------c1 @ offset: 0c2 @ offset: 1i @ offset: 2==============================
Inspecting: MsvcPackedStruct
sizeof(MsvcPackedStruct) = 6
alignof(MsvcPackedStruct) = 1
------------------------------c1 @ offset: 0c2 @ offset: 1i @ offset: 2

可擴展功能

可以封裝為模板工具類,如下:

template<typename T>
struct StructAnalyzer {static void inspect(const std::vector<std::string>& member_names, const std::vector<std::size_t>& member_offsets) {std::cout << "Sizeof: " << sizeof(T) << ", Alignof: " << alignof(T) << "\n";for (size_t i = 0; i < member_names.size(); ++i)std::cout << member_names[i] << " @ offset: " << member_offsets[i] << "\n";}
};

因為 C++ 不支持反射,需要手動提供成員名與偏移。


小結

功能實現
成員偏移計算offsetof(StructType, member)
結構體大小與對齊sizeof, alignof
跨平臺結構體分析支持__attribute__((packed)) / #pragma pack(1)
填充字節檢查(診斷浪費)offsetof + sizeof 分析對比

總結

用法說明
sizeof(type)獲取某個類型的大小
sizeof(expr)獲取表達式類型的大小
獲取數組元素個數sizeof(arr) / sizeof(arr[0])
獲取結構體大小(含對齊)sizeof(Struct)
與模板、static_assert 配合編譯時類型檢查
指針大小與指向對象大小無關

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/91291.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/91291.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/91291.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

內容中臺:在一個地方管理多渠道內容

在數字化競爭愈演愈烈的今天&#xff0c;企業官網、社交平臺、移動應用、郵件營銷等渠道已成為品牌觸達用戶的關鍵接口。內容仍是連接企業與客戶的核心資產。然而&#xff0c;內容創作與分發的復雜性持續攀升&#xff0c;多平臺運營面臨重復維護、更新不一致、資源冗余等諸多挑…

【刷題】東方博宜oj 1307 - 數的計數

樣例輸入&#xff1a; 6輸出&#xff1a; 16 26 126 36 136原版是直接輸出總數量&#xff0c;但我修改了一些&#xff0c;輸出所有的新數。 #include <iostream> #include <vector> #include <string> using namespace std; //int c; void g(int num, string…

阿里云AI代碼助手通義靈碼開發指導

與阿里云一起輕松實現數智化讓算力成為公共服務&#xff1a;用大規模的通用計算&#xff0c;幫助客戶做從前不能做的事情&#xff0c;做從前做不到的規模。讓數據成為生產資料&#xff1a;用數據的實時在線&#xff0c;幫助客戶以數據為中心改變生產生活方式創造新的價值。智能…

設計模式(二十三)行為型:模板方法模式詳解

設計模式&#xff08;二十三&#xff09;行為型&#xff1a;模板方法模式詳解模板方法模式&#xff08;Template Method Pattern&#xff09;是 GoF 23 種設計模式中的行為型模式之一&#xff0c;其核心價值在于定義一個操作中的算法骨架&#xff0c;而將一些步驟延遲到子類中實…

Postgresql 查詢使用正則

今天接到任務&#xff0c;要從數據庫中查詢數據&#xff0c;對于postgresql 我并不熟悉&#xff0c;問了百度&#xff0c;問了通義千問。發現Postgresql 在寫query sql 的時候&#xff0c;可以使用正則匹配&#xff0c;不單是使用like 這種關鍵字。我像發現了新大陸一樣的興奮。…

【WRF-Chem Emissions教程第八期】轉換實用程序

轉換實用程序 8.1 將中間二進制文件轉換為 WRF-Chem 數據文件 文件命名規范與風格 8.2 Binary data file format(中間二進制排放數據文件的格式和結構) FORTRAN 示例程序說明 8.3 Building the WRF-Chemistry emissions conversion code 編譯步驟 驗證編譯結果 8.4 Namelist …

Qt Ribbon效果界面

實現效果&#xff1a;頭文件&#xff1a;#pragma once #include <QMdiArea> #include <QMdiSubWindow> #include <QMainWindow> #include "ui_MainFrame1.h" #include "DockManager.h" #include "DockAreaWidget.h"class Main…

如何修改 MySQL 8.0 的密碼,和忘記密碼時如何修改

要修改 MySQL 8.0 的密碼&#xff0c;可以通過以下幾種方法實現&#xff1a;方法 1&#xff1a;使用 ALTER USER 命令&#xff08;推薦&#xff09;這是 MySQL 8.0 推薦的修改密碼方式&#xff1a;-- 修改當前登錄用戶的密碼 ALTER USER USER() IDENTIFIED BY 新密碼;-- 修改指…

圖像處理控件Aspose.Imaging教程:使用 C# 編程將 CMX 轉換為 PNG

PNG圖像文件格式是廣泛使用的圖像格式之一。這種圖像文件格式提供了增強的共享和顯示功能。另一方面&#xff0c;CMX也是 Corel 應用程序主要使用的圖像文件格式。然而&#xff0c;將 CMX 轉換為 PNG 可以幫助用戶在網絡上查看和共享文件。因此&#xff0c;在本指南中&#xff…

迪麗熱巴寫真壁紙

下載&#xff1a;https://pan.quark.cn/s/a740dbac8274迪麗熱巴絕美寫真&#xff0c;高清壁紙展現獨特魅力&#xff0c;每一張都是視覺盛宴

C++11 std::function 詳解:通用多態函數包裝器

在C11標準中&#xff0c;引入了std::function這一通用多態函數包裝器&#xff0c;定義于<functional>頭文件中。它徹底改變了C中函數對象的使用方式&#xff0c;為不同類型的可調用實體提供了統一的接口。std::function能夠存儲、復制和調用任何可復制構造的可調用目標&a…

Kafka運維實戰 16 - kafka 分區重新分配【實戰】

?? Kafka運維實戰 (17篇) ??Kafka運維實戰 17 - kafka 分區副本從 1 增加到 3【實戰】 ??Kafka運維實戰 16 - kafka 分區重新分配【實戰】 ??Kafka運維實戰 15 - kafka 重設消費者組位移入門和實戰【實戰】 ??Kafka運維實戰 14 - kafka消費者組消費進度(Lag)深入理…

智匯AI,應用領航 | 華宇萬象問數入選2025全景賦能典型案例

7月29日&#xff0c;以“AI城市&#xff1a;數啟新紀元”為主題中關村人工智能與未來城市論壇在中關村國家自主創新示范區展示中心舉辦。本次論壇圍繞人工智能創新應用落地實踐、新型數據基礎設施建設、數據要素價值釋放機制、城市智能治理等關鍵議題&#xff0c;邀請院士專家和…

sqli-labs:Less-7關卡詳細解析

1. 思路&#x1f680; 本關的SQL語句為&#xff1a; $sql"SELECT * FROM users WHERE id(($id)) LIMIT 0,1";注入類型&#xff1a;字符串型&#xff08;單引號、雙括號包裹&#xff09;提示&#xff1a;參數id需以))閉合 同樣無法像常規一樣回顯&#xff0c;php輸出語…

編程算法:從理論基石到產業變革的核心驅動力

文章目錄 算法的本質與效率衡量 基礎算法范式的實踐價值 排序算法的演進與選擇 動態規劃的實用技巧 算法在現代技術棧中的應用 大數據處理的算法框架 編譯器中的算法優化 算法驅動的產業變革 金融領域的算法應用 醫療健康領域的算法創新 制造業的算法優化 算法的未來趨勢 結語 …

深度學習中的注意力機制:原理、應用與未來展望

在人工智能領域&#xff0c;深度學習技術已經取得了巨大的突破&#xff0c;而注意力機制&#xff08;Attention Mechanism&#xff09;作為深度學習中的一個重要概念&#xff0c;正在逐漸改變我們對模型的理解和應用。本文將深入探討注意力機制的原理、在不同領域的應用以及未來…

LeetCode 4:尋找兩個正序數組的中位數

LeetCode 4&#xff1a;尋找兩個正序數組的中位數問題定義與核心挑戰 給定兩個有序&#xff08;升序&#xff09;數組 nums1 和 nums2&#xff0c;要求找到它們的中位數&#xff0c;且算法時間復雜度為 O(log(mn))&#xff08;m 和 n 分別是兩個數組的長度&#xff09;。 中位數…

獨立站如何吃掉平臺蛋糕?DTC模式下的成本重構與利潤躍升

一、成本結構革命&#xff1a;從「流量稅」到「用戶終身價值」亞馬遜賣家需支付15%傭金12%廣告費&#xff0c;導致每$100收入中平臺抽成$27。而成熟獨立站通過SEO&#xff08;自然流量占比超40%&#xff09;和社交媒體內容引流&#xff0c;將獲客成本壓縮至$8-$15。更關鍵的是用…

應用驅動 協同創新:中國人工智能開啟高質量發展新篇章

人工智能技術的突破性發展正引發全球產業格局的深刻變革。在2025年這個關鍵節點&#xff0c;中國以"應用導向"為戰略支點&#xff0c;依托新型舉國體制優勢&#xff0c;正在構建具有中國特色的人工智能發展體系&#xff0c;為全球智能革命貢獻東方智慧。一、戰略布局…

ZKMall商城開源本地部署指南

1. 開發環境配置 以下是開發工具的最低版本要求。在繼續之前&#xff0c;請務必安裝所有必需的依賴項。 工具版本JDK17MySQL5.7.3Redis5.0Maven3.9.5NodeJS20.18.0 1.1 安裝資源 如需詳細的安裝指南&#xff0c;您可以參考以下教程&#xff1a; JDK: 菜鳥教程 Java 環境搭建…