簡體   English   中英

在堆棧C ++上創建的對象中的數據無效

[英]Invalid data in objects created on stack C++

我真的找不到這個問題的更好的標題。

我有三個類: CheckBoxButtonBackground

class CheckBox : public Component
{
private:
    Button m_button;
public:
    CheckBox(const Point &pos, int width, int height, std::string text);
    CheckBox();
};

CheckBox::CheckBox(const Point &pos, int width, int height, string text) : 
    Component(pos, width, height),
    m_button(Button(Point(width-height,0), new Background("button_bg_sample.png", true), new Background("button_bg_onclick_sample.png", true), height, height, 10, "")),
{

}


class Button : public Component
{
private:
    std::string m_text;
    Background* m_pBackground;
    Background* m_pBackgroundOnClick;
    int m_fontSize;
public:
    Button(const Point& pos, Background* pBg, Background* pBgOnClick, int width, int height, int fontSize, std::string title);
    ~Button();

};

Button::Button(const Point& pos, Background* pBg, Background* pBgOnClick, int width, int height, int fontSize, string title) : 
    Component(pos, width, height), 
    m_pBackground(pBg),
    m_pBackgroundOnClick(pBgOnClick),
    m_fontSize(fontSize),
    m_text(title)
{
}


class Background
{
private:
    std::string m_pFileName;
    bool m_bTiling;
    std::vector<unsigned char> m_pImageData;
    unsigned int m_width;
    unsigned int m_height;
    GLuint m_texture; 

    bool load(const std::string& pFileName);
public:
    Background(const std::string& pFileName, bool bTiling);
    ~Background();

    bool draw(const Point &pos, unsigned int width, unsigned int height);
    bool draw(const Point &pos);
};

Background::Background(const string& pFileName, bool bTiling) : 
    m_bTiling(bTiling), 
    m_pFileName(pFileName)
{
    load(pFileName);
}

如您所見, CheckBox類包含Button m_buttonButton類包含Background* m_pBg Background構造函數中,我加載圖像數據並將其存儲在std::vector ,這並不重要 - 我知道它正在工作,因為它已經被檢查過了。

當我創建CheckBox對象時,它的m_button的數據已損壞。 當我嘗試在調試模式下檢查內部圖像數據時,我得到的信息是空的,並且該背景的文件名是"Error reading characters in string" 雖然當我看到在調試模式下一步一步地執行代碼時,我已經看到數據在構造函數中正確加載,但不知何故,當創建對象時,數據已經損壞。

當我在CheckBox類中更改要在堆上創建的m_button字段(指向Button指針,使用new運算符創建的對象)時,一切似乎都正常工作。 正確加載數據並保持這樣。

請問有誰可以解釋一下這個問題的原因是什么?

問題是你不遵守三個規則

Button類管理內存本身,因此當您創建副本或進行分配時,您可能會遇到麻煩。 我沒有挖掘代碼,所以不能肯定這是根(盡管如此仍是一個問題),但我很確定它是。

如果您使用智能指針而不是原始指針來管理資源,則可以避免這一切。

您在CheckBox的構造函數的初始化列表中的堆棧上創建的Button正被復制到m_button字段:

m_button = Button();

default = operator正在做什么,將新創建的Button對象中的每個字段復制到m_button

m_button.height = b.height // Let's assume, that 'b' is the name of this new Button
m_button.width = b.width
m_button.name = b.name
...

現在如果你有一個指向某個對象的指針p1並且你有另一個指針p2並且你將p1分配給p2什么?

int* p1 = new int(5);
int* p2 = p1;

兩個指針現在指向同一個對象! 同樣的事情發生在你的Background* 你有兩個Button指向內存中的同一個Background對象。 但是你在初始化列表中創建的第二個Button正在被銷毀,因為它超出了一個范圍,並且發生了什么PROBABLY(因為我還沒有看到你的Button類的析構函數),你正在破壞Button析構函數中的Background對象。 這就是為什么當您在調試模式下遵循代碼時,您會看到正確創建的Background ,但稍后它會被Button對象銷毀。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM