uint32_t指向与uint8_t指针

时间:2018-06-06 14:04:58

标签: c++ pointers type-conversion

#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?
}

我想创建一个指向与uint8_t指针相同地址的uin32_t指针。这可能不使用新的(地址)吗?我不想丢失地址上的信息。我知道指针只是地址,因此我应该能够将uint32_t指针设置为相同的地址。
此代码产生错误:

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

6 个答案:

答案 0 :(得分:5)

这违反了所谓的Strict Aliasing Rule,因此无法完成。悲伤,但却是真的。

使用memcpy复制数据,在许多情况下,编译器将优化内存复制并生成与使用强制转换相同的代码,但符合标准。

答案 1 :(得分:4)

如前所述,由于严格的别名规则,您无法将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。

答案 2 :(得分:0)

这个问题完全忽略了endian-ness的概念;虽然你的例子的低位和高位字节具有相同的值,但如果交换字节顺序则没有区别;但在它的情况下;你的号码意外错了。

因此,没有可移植的方式来使用结果数字。

答案 3 :(得分:0)

您可以使用 union 做到这一点。如上所述,您必须了解目标设备的字节序,但在大多数情况下,它是小字节序的。还有一点controversy about using unions in such way,但很快它就完成了工作,并且对于某些用途来说已经足够了。

#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
}

答案 4 :(得分:-2)

can be done reinterpret_cast

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

请注意,你在这里使用重型弹药。不推荐摆弄这样的记忆表示,并且可能以令人惊讶的方式出错(比如对齐)。

答案 5 :(得分:-3)

uint32_t *test =(uint32_t*) memory;

uint32_t显示test指向的内存应包含uint32_t。