簡體   English   中英

您可以將結構指針轉換為字符指針嗎?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM