具有继承和指针的内存组织

问题描述 投票:0回答:2

你好,这是代码

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 ? 这是随机的还是我应该了解一些东西?

c++ pointers inheritance memory
2个回答
0
投票

对于结构或类的成员,唯一的规则是后面的成员将具有更高的地址。就是这样!没有关于地址必须高 much 多少的规则(除非避免重叠)。允许编译器在成员之间添加空格(“填充”)。

对于带有

new
的分配和单独声明的变量,您将获得编译器可用的任何地址。无需订购。


-1
投票

不是因为构造函数做了什么。这是因为您正在呼叫

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
© www.soinside.com 2019 - 2024. All rights reserved.