簡體   English   中英

將uint8 *轉換為uint32 *如何工作?

[英]How does casting uint8* to uint32* work?

這里有一個成員函數

uint8* CIwTexture::GetTexels() const;

例如,如果將返回值強制轉換為uint32* ,則強制轉換在這里如何工作? 如果返回值只是8位,那么如何將指向8位數據的指針轉換為32位?

指針僅僅是以地址作為其值的變量。 這意味着所有指針具有相同的大小(不要與“所有指針的數據具有相同的大小”混淆,這是不正確的)。

編譯器處理指針所指向的數據所需的所有信息都是從其類型推斷出來的。 這意味着uint32_t指向的uint32_t將被視為32位數據,而uint8_t數據將被視為8位數據。

所有這些信息僅在編譯時保存,並且編譯器根據其處理的指針生成機器代碼。 這意味着從一個指針到另一個的強制轉換僅與編譯器相關 ,因此它知道在生成代碼時如何處理數據。 在運行時,沒有任何變化,沒有值被復制或移動。

大致來說,您的內存布局可能如下所示: 初始內存布局

括號部分(數據的大小)是對編譯器的提示,因此可以按程序員的意圖對待數據。

當您轉換為uint32_t ,您的內存布局將大致如下所示: 在此處輸入圖片說明

現在,您可以從中推斷出以下幾點:

  • 您的指針完全沒有改變。 它仍然指向相同的位置。
  • 您的內存布局也沒有改變。 您的數據仍然存在,其他內容也是如此。
  • 指針的數據大小確實發生了變化,但是此信息僅在編譯時保留,因此程序的內存布局根本沒有真正改變。

最后,考慮以32位訪問此數據的含義:

  • “其他內容”可能是您自己程序的其他部分,如果您修改該值,則會發生不良情況。
  • “其他內容”可能根本不屬於您的程序,女巫表示它將入侵不屬於該程序的內存。 同樣,壞事還會發生。
  • 也許 “其他內容”是供程序訪問和修改的完全有效的數據。 應該清楚地記錄下來。

例如,如果將其轉換為uin32 *,該轉換如何工作? 我的意思是,如果返回的只是8位,則如何將指向8位數據的指針轉換為32位?

它返回一個內存地址,而不是該內存地址存儲的8位。 該地址指向內存中的某個位置。 當您將其分配給uint32*它仍指向相同的內存位置。

現在,當取消引用該指針時,它將從指針指向的地址的4個連續的內存位置中讀取值(將其與取消引用uint8且僅讀取一個的情況進行比較)。

// somewhere in the memory
uint32 x;

uint8_t* foo()
{
    // Now imagine here x being constructed from 
    // individual bytes or somehow 
    // ...

    // return pointer to the first byte of x as `uint8_t`
    return (uint8_t*)&x;
}

現在,這里的問題就在調用方上-函數簽名中沒有任何內容告訴調用方他需要/可以將其視為uint32_t 在這種情況下,必須對此進行明確記錄。

返回值是指向uint8的指針。 C ++中的指針可以轉換為任何其他類型的指針。 當取消引用該指針時,“魔術”就會開始-取消引用返回的值就是指針的類型。 例如,如果您這樣做:

uint32* ptr = (uint32*)functionThatReturnsPtrToUint8();
uint32 value = *ptr;

然后,“值”變量將僅使用ptr指向的前4個字節,並將其轉換為uint32值(具體實現方式取決於底層系統的字節序)。

返回的不是8位。 返回是一個指針(一個內存地址)。 指針的類型告訴編譯器如何看待內存。 在這種情況下,它表示應一次將存儲器處理一個字節。 如果將指針uint32*uint32* ,則告訴編譯器將數據分成四個字節。 但是,該函數出於某種原因返回了指向字節的指針。 數據可能不打算以四個字節的塊進行處理。 如果將指針轉換為其他類型,則表示正在告訴編譯器以可能不希望的方式使用數據。

指針只是地址,強制類型轉換不會改變地址(指針的值),但會提示編譯器。

但是,當您將指針轉換為其他類型時,會遇到對齊問題,並且編譯器會抱怨。 根本問題是對於某些體系結構,必須以適當的對齊方式訪問內存,例如,不能取消引用奇數地址,否則CPU可能會發生故障/陷阱。

如果您知道自己在做什么,可以安全地忽略它(在這種情況下,我假設返回的指針正確對齊)。

最后,要投射指針,您只需執行以下操作:

uint32_t* p = (uint32_t*) mem;

要么

uint32_t* p = static_cast<uint32_t*>( mem );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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