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

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

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

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

問題定位

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

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

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

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

查找全局文件,的確找到了一個文件存在這樣的問題,當把 #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結(jié)構(gòu)體設(shè)置一字節(jié)對齊方式,CB類使用默認字節(jié)對齊方式。

#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類的實現(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對象

#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

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

問題分析

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

而CB.h沒有包含CA.h,當編譯CB.cpp時,并沒有受到CA.h的影響,CB使用默認字節(jié)對齊方式。

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

相關(guān)文章

  • C++ STL容器stack和queue詳解

    C++ STL容器stack和queue詳解

    這篇文章主要介紹了C++ STL容器stack和queue詳解的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • C++設(shè)計模式之外觀模式(Facade)

    C++設(shè)計模式之外觀模式(Facade)

    這篇文章主要為大家詳細介紹了C++設(shè)計模式之外觀模式(Facade),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • stl常用算法(Algorithms)介紹(stl排序算法、非變序型隊列)

    stl常用算法(Algorithms)介紹(stl排序算法、非變序型隊列)

    這篇文章主要介紹了stl常用算法(Algorithms)介紹(stl排序算法、非變序型隊列),需要的朋友可以參考下
    2014-05-05
  • C++實踐排序函數(shù)模板項目的參考方法

    C++實踐排序函數(shù)模板項目的參考方法

    今天小編就為大家分享一篇關(guān)于C++實踐排序函數(shù)模板項目的參考方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • 標準CSV格式的介紹和分析以及解析算法實例詳解

    標準CSV格式的介紹和分析以及解析算法實例詳解

    這篇文章主要介紹了標準CSV格式的介紹和分析以及解析算法實例詳解的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • C++回溯算法深度優(yōu)先搜索舉例分析

    C++回溯算法深度優(yōu)先搜索舉例分析

    回溯在迷宮搜索中使用很常見,就是這條路走不通,然后返回前一個路口,繼續(xù)下一條路?;厮菟惴ㄕf白了就是窮舉法,下面讓我們一起來看看回溯算法深度優(yōu)先搜索吧
    2022-03-03
  • C語言編程中常見的五種錯誤及對應(yīng)解決方案

    C語言編程中常見的五種錯誤及對應(yīng)解決方案

    這篇文章主要給大家分享的是C語言編程中常見的五種錯誤及對應(yīng)解決方案,詳細內(nèi)容就請跟小編一起進入下面的文章內(nèi)容吧
    2021-10-10
  • C++ 頭文件系列(set)詳解

    C++ 頭文件系列(set)詳解

    一般而言,每個C++/C程序通常由頭文件和定義文件組成。頭文件作為一種包含功能函數(shù)、數(shù)據(jù)接口聲明的載體文件,主要用于保存程序的聲明,而定義文件用于保存程序的實現(xiàn) 。
    2017-02-02
  • C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內(nèi)存中的數(shù)據(jù)都是暫時的,當程序結(jié)束時,它們都將丟失,為了永久性的保存大量的數(shù)據(jù),C語言提供了對文件的操作,這篇文章主要給大家介紹了關(guān)于C語言中文件操作的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • 基于C++的拼多多算法在線筆試題示例

    基于C++的拼多多算法在線筆試題示例

    這篇文章主要介紹了基于C++的拼多多算法在線筆試題,列舉了四個拼多多的算法筆試題,包括分治法、大數(shù)相乘、貪心算法以及迷宮問題,需要的朋友可以參考下
    2017-08-08

最新評論