欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于C++中由于字節(jié)對(duì)齊引起內(nèi)存問題定位分析

 更新時(shí)間:2021年06月10日 09:54:45   作者:wingrez  
前幾天遇到一個(gè)稀奇古怪的問題,在創(chuàng)建對(duì)象的時(shí)候程序異常退出,查找代碼發(fā)現(xiàn)結(jié)構(gòu)體數(shù)組問題,最終把問題簡化得到解決方法,下面小編把我的問題及解決方案分享到腳本之家平臺(tái)供大家參考下

最近遇到了一個(gè)奇怪的問題,在創(chuàng)建對(duì)象時(shí)程序異常退出,具體地,在構(gòu)造函數(shù)中訪問類中最后一個(gè)成員變量時(shí),程序異常退出。

問題定位

查看代碼,發(fā)現(xiàn)該類中有一個(gè)結(jié)構(gòu)體數(shù)組,該結(jié)構(gòu)體在類的外面聲明,用 #pragma pack(push,1) 設(shè)置了一字節(jié)對(duì)齊方式,而類不在這個(gè)作用范圍內(nèi),所以是按照默認(rèn)字節(jié)對(duì)齊方式的。懷疑該問題是因?yàn)?,類的字?jié)對(duì)齊方式和類中的結(jié)構(gòu)體字節(jié)方式不同引起的。但這從理論方面解釋不通。

繼續(xù)定位,在創(chuàng)建對(duì)象之前用sizeof打印類的大小,再在類的構(gòu)造函數(shù)中打印類的大小。發(fā)現(xiàn)這兩個(gè)大小居然不同。這證實(shí)了的確與字節(jié)對(duì)齊有關(guān),創(chuàng)建對(duì)象之前和在構(gòu)造函數(shù)中,兩邊選擇的字節(jié)對(duì)齊方式不同,導(dǎo)致計(jì)算類的大小不同。

但是為什么這兩個(gè)地方的字節(jié)對(duì)齊方式不同呢?

當(dāng)把該類也使用 #pragma pack(push,1) 設(shè)置字節(jié)對(duì)齊方式之后,類的大小又變得相同了。大膽猜測(cè),由于 #pragma pack(push, 1) 是一種棧的結(jié)構(gòu),可能有某個(gè)文件中,設(shè)置了字節(jié)對(duì)齊方式之后,沒有用 #pragma pack(pop) 恢復(fù)。

查找全局文件,的確找到了一個(gè)文件存在這樣的問題,當(dāng)把 #pragma pack(pop) 后加上后,問題解決。

問題模型

我將這個(gè)問題簡化成下面這樣,可以幫助大家更好地理解。
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結(jié)構(gòu)體設(shè)置一字節(jié)對(duì)齊方式,CB類使用默認(rèn)字節(jié)對(duì)齊方式。

#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類的實(shí)現(xiàn)。

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

using namespace std;

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

main.cpp,用于創(chuàng)建CB對(duì)象

#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;
}

編譯上述文件并執(zhí)行,可以得到下面的結(jié)果:

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

可以看到,兩處計(jì)算的類的大小是不同的。在main函數(shù)里,分配了155字節(jié)的空間,而在構(gòu)造函數(shù)中卻認(rèn)為有156字節(jié)的空間,當(dāng)訪問最后一字節(jié)時(shí),程序出現(xiàn)了踩內(nèi)存。

問題分析

為什么main.cpp和CB.cpp認(rèn)為CB的字節(jié)對(duì)齊方式不同呢?
這主要還是因?yàn)閙ain.cpp包含了CA.h,CA.h在main.cpp中展開,CB.h也展開,CA.h中設(shè)置的一字節(jié)對(duì)齊方式,影響到了CB類的聲明,當(dāng)編譯main.cpp時(shí),CB使用一字節(jié)對(duì)齊方式。

而CB.h沒有包含CA.h,當(dāng)編譯CB.cpp時(shí),并沒有受到CA.h的影響,CB使用默認(rèn)字節(jié)對(duì)齊方式。

以上就是關(guān)于C++中由于字節(jié)對(duì)齊引起內(nèi)存問題定位分析的詳細(xì)內(nèi)容,更多關(guān)于c++字節(jié)對(duì)齊內(nèi)存問題的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論