你好,这是代码
class Msg {
public:
int info1;
int info2;
char* msg;
};
class SpeMsg : public Msg {
public:
struct speInfos {
int speInfo1;
int speInfo2;
};
speInfos spe;
};
int main()
{
SpeMsg* sm = new SpeMsg();
sm->info1 = 5;
sm->info2 = 10;
sm->spe.speInfo1 = 15;
sm->spe.speInfo2 = 20;
sm->msg = new char[sizeof("25")];
memcpy(sm->msg, "25", sizeof("25"));
uint8_t * payload = (uint8_t*)sm;
SpeMsg::speInfos* sI = &sm->spe;
cout << "Info 1 : " << &sm->info1 << endl;
cout << "Info 2 : " <<&sm->info2 << endl;
cout << "msg : " <<&sm->msg << endl;
cout << "pointing to : " <<(void *)sm->msg << endl;
cout << "SpeInfo1 : " <<&sm->spe.speInfo1 << endl;
cout << "SpeInfo2 : " <<&sm->spe.speInfo2 << endl;
delete sm->msg;
delete sm;
return 0;
}
我在这里试图了解从构造函数到地址打印在内存中做了什么。
这里的结果是
信息 1:0x1515eb0
信息 2:0x1515eb4
消息:0x1515eb8
指向:0x1515ed0
SpeInfo1:0x1515ec0
SpeInfo2:0x1515ec4
我想知道为什么我的 msg 地址是 0x1515ed0 而不是 0x1515ec8 因为 SpeInfo2 是一个 int ? 这是随机的还是我应该了解一些东西?
对于结构或类的成员,唯一的规则是后面的成员将具有更高的地址。就是这样!没有关于地址必须高 much 多少的规则(除非避免重叠)。允许编译器在成员之间添加空格(“填充”)。
对于带有
new
的分配和单独声明的变量,您将获得编译器可用的任何地址。无需订购。
不是因为构造函数做了什么。这是因为您正在呼叫
new
接线员。如果你这样做,你不能指望任何内存对齐。
如果你想要内存对齐,试试这个:
#include <iostream>
#include <array>
#include <boost/static_string.hpp>
constexpr auto MaxMsgSize = 256;
using MsgText = boost::static_string<MaxMsgSize>;
class Msg
{
public:
int info1;
int info2;
MsgText msg;
};
class SpeMsg : public Msg {
public:
struct speInfos {
int speInfo1;
int speInfo2;
};
speInfos spe;
};
int main()
{
auto sm = SpeMsg{};
sm.info1 = 5;
sm.info2 = 10;
sm.spe.speInfo1 = 15;
sm.spe.speInfo2 = 20;
sm.msg = "25";
const SpeMsg::speInfos& sI = sm.spe;
std::cout << "Info 1 : " << &sm.info1 << std::endl;
std::cout << "Info 2 : " << &sm.info2 << std::endl;
std::cout << "msg : " << &sm.msg << std::endl;
std::cout << "pointing to : " << &sm.msg << std::endl;
std::cout << "SpeInfo1 : " << &sm.spe.speInfo1 << std::endl;
std::cout << "SpeInfo2 : " << &sm.spe.speInfo2 << std::endl;
return 0;
}
这打印:
Info 1 : 0x7ffd60e7b148
Info 2 : 0x7ffd60e7b14c
msg : 0x7ffd60e7b150
pointing to : 0x7ffd60e7b150
SpeInfo1 : 0x7ffd60e7b254
SpeInfo2 : 0x7ffd60e7b258