假设我在 Message.h 中得到了这个:
#ifndef _MESSAGE_H_
#define _MESSAGE_H_
#include <stdio.h>
#include <string.h>
enum PRIMITIVE{
MESSAGE_1 = 100,
MESSAGE_2,
};
enum { MSG_SIZE_IN_BYTES = 1024 };
class Header{
protected:
Header(PRIMITIVE prim, u_int32 transNum) : m_primitive(prim), m_transNum(transNum) { }
public:
// access
PRIMITIVE primitive() const { return m_primitive; }
u_int32 transNum() const { return m_transNum; }
virtual ~Header(){}
private:
PRIMITIVE m_primitive;
u_int32 m_transNum;
};
class Message
{
public:
Message() { reset(); }
// access
char* addr() { return reinterpret_cast<char*>(m_buffer); }
const char* addr() const { return reinterpret_cast<const char*>(m_buffer); }
u_int32 size() { return sizeof(m_buffer); }
// msgs
Header* msgHeader() { return reinterpret_cast<Header*>(addr()); }
const Header* msgHeader() const { return reinterpret_cast<const Header*>(addr()); }
// modify
void reset() {
memset(&m_buffer, 0, MSG_SIZE_IN_BYTES);
}
private:
u_int64 m_buffer[MSG_SIZE_IN_BYTES / sizeof(u_int64)];
};
#endif
在main.cpp
中,我将m_buffer
in Message 转换为Header
类型。关键是我可以根据Header
布局访问内存:
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
int main(int argc, char *argv[]){
Message msg;
char* content = msg.addr();
int prim = 100;
int trans_num = 1;
memcpy(content, &prim, 4);
memcpy(content+4, &trans_num, 4);
const Message::Header* hdr = msg.msgHeader();
Message::PRIMITIVE hdr_prim = hdr->primitive();
u_int32 hdr_transNum = hdr->transNum();
cout << "Memory address of Message: " << &msg << endl;
cout << "Memory address of Message buffer: " << (void*) msg.addr() << endl;
cout << "Memory address of content: " << content << endl;
cout << "Memory address of Header: " << hdr << endl;
cout << "Memory address of m_primitive in Header: " << &hdr_prim << endl;
cout << "Memory address of m_transNum in Header: " << &hdr_transNum << endl;
cout << "Primitive in Header: " << prim << endl;
cout << "Trans num in Header: " << transNum << endl;
}
Header* hdr
应该指向与 相同的内存地址,Message msg
并且m_primitive
应该与 位于相同的地址Header* hdr
,并且m_transNum
是&m_primitive + 4
。
但是,这是实际值:
Memory address of Message: 0x699520
Memory address of Message buffer: 0x699520
Memory address of content: 0x699520
Memory address of Header: 0x699520
Memory address of m_primitive in Header: 0x7f2ec2f2738c
Memory address of m_transNum in Header: 0x7f2ec2f27388
Primitive in Header: 1
Trans num in Header: 1953719668
m_primitive
并m_transNum
指向一个完全随机的位置并得到垃圾值!怎么会发生?reinterpret_cast
应该通过转换为不同类型的指针来根据类类型更改布局。
另外,如果它返回一个副本,则 的值m_primitive
应该是 100,并且m_transNum
应该是 1,因为我memcpy
进入char* content
了msg
. 但价值观是错误的。