Program Received signal SIGSEGV

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Netzschleicher
Knows some wx things
Knows some wx things
Posts: 25
Joined: Tue Aug 17, 2010 6:48 pm
Location: Germany

Program Received signal SIGSEGV

Post by Netzschleicher »

Hi at all,

i want to Show a wxFrame by clicking on a Button at my MainFrame. By the second Click, i want to close the wxFrame, or if the Frame was minimized to show them. Also the Frame can be closed on Close the Frame with the Close 'X' on the Frame.
But when the Frame was closed an i click on the Button again, i get an SIGSEGV Error at the Line 'if (memoryeditor->IsIconized()) {'. By watching the Pointer is seems to have a Adress but this is not valid?

What is my mistake?

Code: Select all

#ifndef MAINFRAME_H
#define MAINFRAME_H
//---------------------------------------------------------------------------------
#include "ui_mainframe.h"
//---------------------------------------------------------------------------------
class MemoryEditor;
//---------------------------------------------------------------------------------
class MainFrame : public Ui_MainFrame {
        DECLARE_EVENT_TABLE()

    private:    // Attributes
        MemoryEditor *memoryeditor;

    public:     // Attributes

    public:     // Constructor & Destructor
        MainFrame (wxWindow *parent);
        virtual ~MainFrame();

    protected:  // Event Methods
        void onShowMemoryEditor (wxCommandEvent &event);

    private:    // Methods

    public:     // Methods
};

//---------------------------------------------------------------------------------
#endif // MAINFRAME_H

Code: Select all

#include "mainframe.h"
#include "memoryeditor.h"
//---------------------------------------------------------------------------------
BEGIN_EVENT_TABLE (MainFrame, wxFrame)
    EVT_BUTTON (ID_BUTTON_SHOW_MEMORY_EDITOR,  MainFrame::onShowMemoryEditor)
END_EVENT_TABLE()
//---------------------------------------------------------------------------------
MainFrame::MainFrame (wxWindow *parent) : Ui_MainFrame (parent) {
}

//---------------------------------------------------------------------------------
MainFrame::~MainFrame() {
    wxDELETE (memoryeditor);
}

//---------------------------------------------------------------------------------
void MainFrame::onShowMemoryEditor (wxCommandEvent &event) {
    if (memoryeditor == NULL) {
        memoryeditor = new MemoryEditor (this);
    }
    if (memoryeditor != NULL) {
        if (memoryeditor->IsIconized()) {    <-- error after closing the wxFrame an want to show again
            memoryeditor->Restore();
        }
        else if (memoryeditor->IsVisible()) {
            memoryeditor->Close ();
        }
        else {
            memoryeditor->Show();
        }
    }
}

//---------------------------------------------------------------------------------
Manolo
Can't get richer than this
Can't get richer than this
Posts: 828
Joined: Mon Apr 30, 2012 11:07 pm

Re: Program Received signal SIGSEGV

Post by Manolo »

I guess you don't update "memoryeditor" pointer after memoryeditor->Close()
Can't know, not enough code.
Netzschleicher
Knows some wx things
Knows some wx things
Posts: 25
Joined: Tue Aug 17, 2010 6:48 pm
Location: Germany

Re: Program Received signal SIGSEGV

Post by Netzschleicher »

What do you mean with update?
The memoryeditor Pointer is a private Member of the Main Frame class.
What more Code do you need?
User avatar
doublemax
Moderator
Moderator
Posts: 19162
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Program Received signal SIGSEGV

Post by doublemax »

The default behavior of a wxFrame is to destroy itself when it's closed. After that the pointer "memoryeditor" is invalid.
Use the source, Luke!
Manolo
Can't get richer than this
Can't get richer than this
Posts: 828
Joined: Mon Apr 30, 2012 11:07 pm

Re: Program Received signal SIGSEGV

Post by Manolo »

If you close that other frame and don't set memoryeditor = NULL (which is done with wxDELETE(memoryeditor)) then the next time you click the button the memoryeditor->IsIconized() branch is executed with an invalid pointer.
Netzschleicher
Knows some wx things
Knows some wx things
Posts: 25
Joined: Tue Aug 17, 2010 6:48 pm
Location: Germany

Re: Program Received signal SIGSEGV

Post by Netzschleicher »

Can the Pointer set to NULL, or how can i test if the Pointer is valid?
Manolo
Can't get richer than this
Can't get richer than this
Posts: 828
Joined: Mon Apr 30, 2012 11:07 pm

Re: Program Received signal SIGSEGV

Post by Manolo »

There are two points where you must NULL that pointer:

a) Right after memoryeditor->Close()

b) In your MemoryEditor ctor pass a pointer to the main frame. Have a "make memoryeditor NULL" method in the main frame.
When the MemoryEditor closes (handle this event), call that method in the main frame: myMainFrame->SetEPNull();
User avatar
doublemax
Moderator
Moderator
Posts: 19162
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Program Received signal SIGSEGV

Post by doublemax »

Another option is to use a smart pointer.
https://docs.wxwidgets.org/trunk/classw ... _01_4.html
Use the source, Luke!
Netzschleicher
Knows some wx things
Knows some wx things
Posts: 25
Joined: Tue Aug 17, 2010 6:48 pm
Location: Germany

Re: Program Received signal SIGSEGV

Post by Netzschleicher »

what do you think about this construct?

Code: Select all

if ((memoryeditor == NULL) || (memoryeditor->IsBeingDeleted() == true)) {
        memoryeditor = new MemoryEditor (this);
    }
Manolo
Can't get richer than this
Can't get richer than this
Posts: 828
Joined: Mon Apr 30, 2012 11:07 pm

Re: Program Received signal SIGSEGV

Post by Manolo »

By the time IsBeingDeleted() is called, you can't be sure that the frame still exists, so that pointer can point to an invalid instance.
Netzschleicher
Knows some wx things
Knows some wx things
Posts: 25
Joined: Tue Aug 17, 2010 6:48 pm
Location: Germany

Re: Program Received signal SIGSEGV

Post by Netzschleicher »

Ok. I thought this can be an easy solution.
Netzschleicher
Knows some wx things
Knows some wx things
Posts: 25
Joined: Tue Aug 17, 2010 6:48 pm
Location: Germany

Re: Program Received signal SIGSEGV

Post by Netzschleicher »

So, a few days later, i have tested Manolos suggested solution.
It works very fine.

Following the Code i used now.

Code: Select all

#ifndef MAINFRAME_H
#define MAINFRAME_H
//---------------------------------------------------------------------------------
#include "ui_mainframe.h"
//---------------------------------------------------------------------------------
class MainFrame : public Ui_MainFrame {
        DECLARE_EVENT_TABLE()

    private:    // Attributes

    public:     // Attributes

    public:     // Constructor & Destructor
        MainFrame (wxWindow *parent);
        virtual ~MainFrame();

    protected:  // Event Methods
        void onShowMemoryEditor (wxCommandEvent &event);

    private:    // Methods

    public:     // Methods
        void SetMemoryEditorZero();
};

//---------------------------------------------------------------------------------
#endif // MAINFRAME_H

Code: Select all

#include "mainframe.h"
#include "memoryeditor.h"
//---------------------------------------------------------------------------------
BEGIN_EVENT_TABLE (MainFrame, wxFrame)
    EVT_BUTTON (ID_BUTTON_SHOW_MEMORY_EDITOR,  MainFrame::onShowMemoryEditor)
END_EVENT_TABLE()
//---------------------------------------------------------------------------------
MainFrame::MainFrame (wxWindow *parent) : Ui_MainFrame (parent) {
    SetMemoryEditorZero();
}

//---------------------------------------------------------------------------------
MainFrame::~MainFrame() {
}

//---------------------------------------------------------------------------------
void MainFrame::onShowMemoryEditor (wxCommandEvent &event) {
    if (memoryeditor == nullptr)  {
        memoryeditor = new MemoryEditor (this);
    }
    if (memoryeditor != nullptr) {
        if (memoryeditor->IsIconized()) {
            memoryeditor->Restore();
            memoryeditor->Raise();
        }
        else if (memoryeditor->IsVisible()) {
            memoryeditor->Close ();
        }
        else {
            memoryeditor->Show();
            memoryeditor->Raise();
        }
    }
}

//---------------------------------------------------------------------------------
void MainFrame::SetMemoryEditorZero() {
    memoryeditor = nullptr;
}

//---------------------------------------------------------------------------------

Code: Select all

#ifndef MEMORYEDITOR_H
#define MEMORYEDITOR_H
//---------------------------------------------------------------------------------
#include "ui_memoryeditor.h"
//---------------------------------------------------------------------------------
class MainFrame;
//---------------------------------------------------------------------------------
class MemoryEditor : public Ui_MemoryEditor {

    private:    // Attributes
        MainFrame *mainframe;

    public:     // Attributes

    public:     // Constructor & Destructor
        MemoryEditor (wxWindow *parent);
        virtual ~MemoryEditor();

    protected:  // Event Methods

    private:    // Methods

    public:     // Methods
};

//---------------------------------------------------------------------------------
extern MemoryEditor *memoryeditor;
//---------------------------------------------------------------------------------
#endif // MEMORYEDITOR_H

Code: Select all

#include "memoryeditor.h"
#include "mainframe.h"
//---------------------------------------------------------------------------------
MemoryEditor *memoryeditor;
//---------------------------------------------------------------------------------

//---------------------------------------------------------------------------------
MemoryEditor::MemoryEditor (wxWindow *parent) : Ui_MemoryEditor (parent) {
    MainFrame *mainframe = dynamic_cast<MainFrame *> (parent);
}

//---------------------------------------------------------------------------------
MemoryEditor::~MemoryEditor() {
    mainframe->SetMemoryEditorZero();
}

//---------------------------------------------------------------------------------
Post Reply