文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

关于C++中由于字节对齐引起内存问题定位分析

2024-04-02 19:55

关注

最近遇到了一个奇怪的问题,在创建对象时程序异常退出,具体地,在构造函数中访问类中最后一个成员变量时,程序异常退出。

问题定位

查看代码,发现该类中有一个结构体数组,该结构体在类的外面声明,用 #pragma pack(push,1) 设置了一字节对齐方式,而类不在这个作用范围内,所以是按照默认字节对齐方式的。怀疑该问题是因为,类的字节对齐方式和类中的结构体字节方式不同引起的。但这从理论方面解释不通。

继续定位,在创建对象之前用sizeof打印类的大小,再在类的构造函数中打印类的大小。发现这两个大小居然不同。这证实了的确与字节对齐有关,创建对象之前和在构造函数中,两边选择的字节对齐方式不同,导致计算类的大小不同。

但是为什么这两个地方的字节对齐方式不同呢?

当把该类也使用 #pragma pack(push,1) 设置字节对齐方式之后,类的大小又变得相同了。大胆猜测,由于 #pragma pack(push, 1) 是一种栈的结构,可能有某个文件中,设置了字节对齐方式之后,没有用 #pragma pack(pop) 恢复。

查找全局文件,的确找到了一个文件存在这样的问题,当把 #pragma pack(pop) 后加上后,问题解决。

问题模型

我将这个问题简化成下面这样,可以帮助大家更好地理解。
CA.h,CA类的声明,模拟只push,没pop的文件


#ifndef CA_H
#define CA_H

#include <iostream>
using namespace std;

#pragma pack(push, 1)

class CA {
    int a;
    char b;
};

#endif

CB.h,CB类的声明。St结构体设置一字节对齐方式,CB类使用默认字节对齐方式。


#ifndef CB_H
#define CB_H

#include <iostream>
using namespace std;

#pragma pack(push,1)

struct St {
    int a1;
    int a2;
    int a3;
    char a4;
    char a5;
};

#pragma pack(pop)

class CB {
public:
    CB();
    int a1;
    int a2;
    int a3;
    char a4;
    char a5;
    St a6[10];
    bool a7;
};

#endif

CB.cpp,CB类的实现。


#include "CB.h"
#include <iostream>

using namespace std;

CB::CB()
{
    cout << "constructor: sizeof(CB) = ";
    cout << sizeof(CB) << endl;
}

main.cpp,用于创建CB对象


#include "CA.h"
#include "CB.h"
#include <iostream>

using namespace std;

int main()
{
    cout << "main: sizeof(CB) = ";
    cout << sizeof(CB) << endl;
    CB *pCB = new CB;
}

编译上述文件并执行,可以得到下面的结果:

main: sizeof(CB) = 155
constructor: sizeof(CB) = 156

可以看到,两处计算的类的大小是不同的。在main函数里,分配了155字节的空间,而在构造函数中却认为有156字节的空间,当访问最后一字节时,程序出现了踩内存。

问题分析

为什么main.cpp和CB.cpp认为CB的字节对齐方式不同呢?
这主要还是因为main.cpp包含了CA.h,CA.h在main.cpp中展开,CB.h也展开,CA.h中设置的一字节对齐方式,影响到了CB类的声明,当编译main.cpp时,CB使用一字节对齐方式。

而CB.h没有包含CA.h,当编译CB.cpp时,并没有受到CA.h的影响,CB使用默认字节对齐方式。

以上就是关于C++中由于字节对齐引起内存问题定位分析的详细内容,更多关于c++字节对齐内存问题的资料请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯