簡體   English   中英

分配指針時出現分段錯誤

[英]Segmentation Fault when Assigning Pointer

當我嘗試初始化具有指向其他 class 對象的 class 指針變量的 class 時,我得到分段錯誤。 下面的示例代碼片段。

我已經嘗試使用'new'關鍵字初始化變量以首先清空類,以及在分配之前手動使用 malloc,並嘗試只分配變量而沒有任何花哨的分配並且沒有任何效果。

// Caller
void Application::run()
{
    Network network(this);
    network.start();
}

// Seg fault here, at the line that assigns window
Network::Network(Application *app)
{
    application = new Application();
    window = new sf::RenderWindow();
        application = app;
    window = app->window;
}

// Header for Network
class Network 
{
    public:
        Application* application;
        sf::RenderWindow* window;
    // Functions
    Network(Application *app);
        void start();
        void networkLoop();
    private:
    protected:
};

// Header for Application
class Application 
{
    public:
    sf::RenderWindow* window;
    Theme* theme;
    // Functions
    Application();
    void run();
    private:
    protected:
};

// Main
#include "application.h"
#include <X11/Xlib.h>

int main()
{
    XInitThreads();
    Application* app;
    app->run();
}

我對使用 C++ 很陌生,所以請原諒我明顯的 memory 錯誤。 我已經嘗試尋找解決方案,但我發現沒有任何效果。 我接受指向 Application 的指針作為構造函數的輸入,因為我希望 RenderWindow 和 Application 的相同實例跨其他對象保存。

編輯:我覺得很愚蠢,但我改變了main()以使用Application Application app而不是Application* app程序創建應用程序,它似乎已經修復了它。 但是仍然:有人可以解釋為什么它有效而使用指針無效嗎?

問題出在你的main()

int main()
{
    XInitThreads();
    Application* app;
    app->run();
}

您需要在這里使用new並分配您的Application

int main()
{
    XInitThreads();
    Application* app = new Application(...);
    app->run();
}

但是,不要Network中執行此操作。 這將產生 memory 泄漏。 改為這樣做:

Network::Network(Application *app)
{
    application = app;
    window = app->window;
}

編輯:

有人可以解釋為什么這有效而使用指針無效嗎?

因此,指針本身不會分配任何 memory。 它們只是指針。 他們持有地址。 他們不會自己分配 memory 來允許這樣的事情:

int a =0;
int *b = &a; // holds address of a

如果指針在這里分配數據,可能會導致 memory 泄漏或其他事情。 因此,如果你想持有一個新的 object 獨立於其他變量,你需要使用new或一些智能指針:

int* c = new int; // c holds an int independent of a or b

因此,如果你只是做這樣的事情:

int* d;

d本身沒有在其 position 分配的 memory。 它是一個占位符,可以保存任何地址。 它可以保存現有地址或新地址。 但是它需要存儲一些有效的地址才能使用它。

如果要創建Application的實例,則必須使用new分配它,或者正如其他人指出的那樣,甚至根本不使用指針,這實際上是推薦的操作過程:

int main()
{
    XInitThreads();
    Application app;
    app.run();
}

要回答您的編輯,之間的區別

Application* app;

Application app;

是什么被分配和構造,什么沒有。

在第一個示例中,編譯器在堆棧中留出足夠的空間來保存一個指針,但沒有為它可能指向的內容留出任何空間——您需要使用new手動執行此操作。 這就是您的程序無法運行的原因 - 您有一個指針空間,但是當您使用->取消引用該指針時,另一端沒有Application等待。 您告訴它找到一個Application並獲取window屬性並將其存儲在其他地方,但是從未創建過window屬性。

在第二個示例中,編譯器為完整的Application object 留出足夠的空間,並為您調用構造函數。 因此,當您這次取消引用指針時,會有一個等待使用的Application


我想添加另一條信息。 在第一個例子中,指針不是對象,也沒有要調用的構造函數,所以如果你不給它們賦值,它們的初始值基本上是隨機的——無論當時在堆棧中。 因此,您的指針不僅沒有指向Application ,甚至可能沒有指向可用的 memory 位置,這就是您遇到分段錯誤的原因。

暫無
暫無

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

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