结构中引用的间接指针的意外地址与普通变量的相同声明相反?
unexpected address for a referenced indirected pointer in a struct as opposed to same declaration with a plain variable?
我有一个结构,其中包含一个字节数组和对数组中各个点的多个类型转换引用。字节 4:7 可能被解释为浮点数、int32_t 或 uint32_t,由通过串行连接接收的数据包中的其他字段确定。为了使访问变得简单(例如 message.argument.F
用于浮点解释),我对间接类型转换指针进行了多次引用。但是当我 运行 程序时,我在尝试写入结构中的引用时遇到段错误。据我所知,问题与容器有关,如示例片段 (cpp shell: http://cpp.sh/3vmoy):
所示
#include <iostream>
#include <cstring>
using namespace std;
#define PACKET_SIZE 9
#define ARG_I 4
struct Message{
uint8_t bytes[PACKET_SIZE];
uint8_t* argbytes = static_cast<uint8_t*>(argp);
float& argf = *static_cast<float*>(argp);
void* argp = &bytes[ARG_I];
} message;
int main(){
// USING STRUCT
cout << "Using message struct" << endl;
cout << message.argp << endl; // the pointer at index stored in struct
cout << static_cast<float*>(message.argp) << endl; // casting the pointer to a float* - should be the same
cout << &message.argf << endl; // the address of the float reference cast from argp, ** should be the same BUT IS NOT **
// RAW VARS
uint8_t bytes[PACKET_SIZE];
void* argp = &bytes[ARG_I];
float& argf = *static_cast<float*>(argp);
cout << endl << "using raw vars" << endl;
cout << argp << endl; // a pointer to a byte in an array of bytes.
cout << static_cast<float*>(argp) << endl; // the same pointer cast as a float*
cout << &argf << endl; // the address of a float reference cast from argp, **should be the same AND IS.**
}
我希望看到相同的指针地址、类型转换指针和间接指针的引用地址。我 do 看到如果我创建一个数组和 pointer/reference 作为独立变量,但不是针对结构中的相同声明。我缺乏什么神秘的知识来解释这种行为(或者我忽略了什么愚蠢的事情?)
我解决这个问题的想法是 a) 忽略它并根据需要对指针进行类型转换,或者 b) 创建一些 setter/getter 函数来访问串行“数据包”的参数部分。
两个可供选择的代码块之间有两个主要的根本区别。
void* argp = &bytes[ARG_I];
float& argf = *static_cast<float*>(argp);
这里先构造初始化argp
,再构造初始化argf
.
float& argf = *static_cast<float*>(argp);
void* argp = &bytes[ARG_I];
而在这里,它没有。
这会先初始化 argf
,然后 argp
。这样做的后果应该是很明显的。
注意:我在这里忽略了所有违反别名规则的行为,它们很可能是进一步未定义行为的来源。
我有一个结构,其中包含一个字节数组和对数组中各个点的多个类型转换引用。字节 4:7 可能被解释为浮点数、int32_t 或 uint32_t,由通过串行连接接收的数据包中的其他字段确定。为了使访问变得简单(例如 message.argument.F
用于浮点解释),我对间接类型转换指针进行了多次引用。但是当我 运行 程序时,我在尝试写入结构中的引用时遇到段错误。据我所知,问题与容器有关,如示例片段 (cpp shell: http://cpp.sh/3vmoy):
#include <iostream>
#include <cstring>
using namespace std;
#define PACKET_SIZE 9
#define ARG_I 4
struct Message{
uint8_t bytes[PACKET_SIZE];
uint8_t* argbytes = static_cast<uint8_t*>(argp);
float& argf = *static_cast<float*>(argp);
void* argp = &bytes[ARG_I];
} message;
int main(){
// USING STRUCT
cout << "Using message struct" << endl;
cout << message.argp << endl; // the pointer at index stored in struct
cout << static_cast<float*>(message.argp) << endl; // casting the pointer to a float* - should be the same
cout << &message.argf << endl; // the address of the float reference cast from argp, ** should be the same BUT IS NOT **
// RAW VARS
uint8_t bytes[PACKET_SIZE];
void* argp = &bytes[ARG_I];
float& argf = *static_cast<float*>(argp);
cout << endl << "using raw vars" << endl;
cout << argp << endl; // a pointer to a byte in an array of bytes.
cout << static_cast<float*>(argp) << endl; // the same pointer cast as a float*
cout << &argf << endl; // the address of a float reference cast from argp, **should be the same AND IS.**
}
我希望看到相同的指针地址、类型转换指针和间接指针的引用地址。我 do 看到如果我创建一个数组和 pointer/reference 作为独立变量,但不是针对结构中的相同声明。我缺乏什么神秘的知识来解释这种行为(或者我忽略了什么愚蠢的事情?)
我解决这个问题的想法是 a) 忽略它并根据需要对指针进行类型转换,或者 b) 创建一些 setter/getter 函数来访问串行“数据包”的参数部分。
两个可供选择的代码块之间有两个主要的根本区别。
void* argp = &bytes[ARG_I];
float& argf = *static_cast<float*>(argp);
这里先构造初始化argp
,再构造初始化argf
.
float& argf = *static_cast<float*>(argp);
void* argp = &bytes[ARG_I];
而在这里,它没有。
这会先初始化 argf
,然后 argp
。这样做的后果应该是很明显的。
注意:我在这里忽略了所有违反别名规则的行为,它们很可能是进一步未定义行为的来源。