繁体   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