簡體   English   中英

uint32_t 指針指向與 uint8_t 指針相同的位置

[英]uint32_t pointer to the same location as uint8_t pointer

#include <iostream>

int main(){
    uint8_t memory[1024];
    memory[0] = 1;
    memory[1] = 1;
    uint32_t *test = memory;
    //is it possible to get a value for *test that would be in this example 257?
}

我想創建一個 uin32_t 指針,指向與 uint8_t 指針相同的地址。 這可能不使用 new(adress) 嗎? 我不想丟失地址中的信息。 我知道指針只是地址,因此我應該能夠將 uint32_t 指針設置為相同的地址。
此代碼產生錯誤:

invalid conversion from 'uint8_t*' to 'uint32_t*' in initialization

這將違反所謂的嚴格別名規則,因此無法做到。 悲傷,但真實。

使用memcpy復制數據,在許多情況下,編譯器將優化內存復制並生成與使用 cast 相同的代碼,但以符合標准的方式。

如前所述,由於嚴格的別名規則,您無法將uint8_t *轉換為uint32_t * ,但您可以將uint32_t *轉換為unsigned char *

#include <iostream>

int main(){
    uint32_t test[1024/4] = {}; // initialize it!
    auto memory = reinterpret_cast<unsigned char *>( test );
    memory[0] = 1;
    memory[1] = 1;
    std::cout << test[0] << std::endl;
}

由於Endianness ,這不是可移植的代碼,但至少它沒有 UB。

這個問題完全忽略了字節序的概念; 雖然您的示例的低字節和高字節具有相同的值,但如果交換字節順序,則沒有區別; 但在這種情況下; 你的號碼會出乎意料的錯誤。

因此,沒有可移植的方式來使用結果數字。

你可以用union做到這一點。 如上所述,您必須了解目標設備的字節序,但在大多數情況下,它是小字節序的。 以這種方式使用聯合也存在一些爭議,但很快它就完成了工作,並且對於某些用途來說已經足夠了。

#include <iostream>

int main(){
    union {
        uint8_t memory[1024] = {};
        uint32_t test[1024/4];
    };
    
    memory[0] = 1;
    memory[1] = 1;
    std::cout << test[0]; // 257
}

可以通過 reinterpret_cast 完成

uint32_t *test = reinterpret_cast<uint32_t*>(memory);

但是請注意,您在這里使用的是重型武器。 不建議擺弄這樣的內存表示,否則可能會以令人驚訝的方式(例如對齊)出錯。

uint32_t *test =(uint32_t*) memory;

uint32_t 表明test指向的內存應該包含 uint32_t 。

暫無
暫無

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

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