• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

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

c++ 搞代码 4年前 (2022-01-06) 27次浏览 已收录 0个评论
文章目录[隐藏]

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

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

问题定位

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

继续定位,在创建对象之前用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  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  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  using namespace std; CB::CB() { cout << "constructor: sizeof(CB) = "; cout << sizeof(CB) << endl; }

main.cpp,用于创建CB对象

 #include "CA.h" #include "CB.h" #include  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++中由于字节对齐引起内存问题定位分析的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:关于C++中由于字节对齐引起内存问题定位分析

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址