#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
答案 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。