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
では、 in Message をtypemain.cpp
にキャストしました。ポイントは、レイアウトに従ってメモリにアクセスできることです。m_buffer
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
はずです。しかし、値は間違っています。memcpy
char* content
msg