[英]Can you cast struct pointer to char pointer?
我有一個名為結構Characters
,即結構命名的變量a
,和一個指向名為焦pChar
和我想的值更改FirstChar
通過在27 pChar
struct Characters {
short CharCount;
char FirstChar;
char SecondChar;
char ThirdChar;
};
struct Characters a = {3, 4, 5, 6};
char* pChar;
pChar = (char*)&a;
*(pChar+2) = 27;
我可以安全地將 struct a 轉換為char*
嗎? 填充是否會添加到結構的末尾? 如果我使用*(pChar+2)
我能保證它指的是FirstChar
嗎?
我可以安全地將 struct a 轉換為 char* 嗎?
演員本身是安全的。 訪問指針的內容*(pChar+2) = 27;
不安全。 正式它可能會調用未定義的行為,因為它違反了aliasing 。
(就別名規則而言,使用 char* 很好,但是當將值 27 寫入隨機字節時,正式無法保證結果會是什么。而且您可能正在寫入填充字節。)
填充是否會添加到結構的末尾?
填充可以添加到結構中的任何地方,除了最開始的地方。
在實踐中,做這樣的事情可能是相當安全的,即使這是不推薦的和正式未定義的行為。 我還沒有遇到過不能安全和確定地工作的系統。 但是你必須確保沒有填充:
struct Numbers {
short CharCount;
char FirstChar;
char SecondChar;
char ThirdChar;
};
static_assert(sizeof(struct Numbers) ==
sizeof(short) +
sizeof(char) +
sizeof(char) +
sizeof(char),
"Padding found");
要實際禁用填充,通常有一些非標准方式,例如#pragma pack(1)
。
編輯
可靠地獲取結構成員地址的最佳和最便攜的方法可能是這樣的:
#include <stddef.h>
struct Numbers x;
char* ptr = (char*)&x + offsetof(struct Numbers, FirstChar);
您可以將任何指針類型轉換為另一種指針類型,並且在它指向相同內存空間的意義上仍然可以工作,如果這就是您的要求。
但是,如果您按照自己的方式修改結構中的變量,則很難確定會發生什么,主要是因為內存對齊。
您可以通過設置#pragma pack(1)
在大多數編譯器中抑制內存對齊。
如果你這樣做,並且char
是 1 字節長, short
是 2 字節長(它可能並不總是這樣),只有這樣才能保證修改pChar[2]
會改變FirstChar
的值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.