首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C++ 結構體首個成員為 char 類型時無法正確獲取地址的原因分析

     編輯:程式設計疑難解答

現象描述

定義一個結構體,其第一個成員為 char 類型。在主函數中創建該結構體對象,並嘗試獲取該 char 成員的地址並打印。在 Windows XP 及 Android AIDE 環境下均顯示亂碼(如負數地址 -2639232),但若將首個成員改為 int 等 4 字節類型則能正常輸出地址。

根本原因:內存對齊與指針打印格式

// 示例輸出地址差值
-2639232  // char 成員地址
-2639228  // 下一個 int 成員地址(差 4 字節)
-2639220  // 再下一個 int 成員地址(差 4 字節)
  1. 編譯器按 4 字節對齊:雖然 char 只有 1 字節,但編譯器為了訪問效率,會在其後填充 3 字節 padding,導致下一個成員起始地址相差 4 字節。
  2. 地址最高位為 1 顯示為負數:32 位系統下,棧內存地址通常超過 0x80000000,符號位為 1,若用 %d(有符號整數)打印指針,會被解釋為負數。應使用 %p 並轉型為 void*。

正確打印姿勢

struct Demo { char c; int a; double d; };
Demo obj;
printf("char 地址: %p\n", (void*)&obj.c);
printf("int  地址: %p\n", (void*)&obj.a);
printf("double 地址: %p\n", (void*)&obj.d);

避坑指南

  • 打印指針永遠用 %p + (void*),不要用 %d、%x 或 %ld。
  • 結構體設計時,將較大類型(double、long long、指針)放在前面,可減少填充字節,節省內存。
  • 使用 #pragma pack(n) 或 __attribute__((packed)) 可控制對齊,但可能降低訪問性能。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved