简体   繁体   English

单击多个 wxButton 时,Linux C++ wxWidgets 出现分段错误

[英]Linux C++ wxWidgets giving segmentation fault when clicking multiple wxButtons

I'm having issues with my wxWidgets application when clicking a wxButton then clicking another wxButton.单击 wxButton 然后单击另一个 wxButton 时,我的 wxWidgets 应用程序出现问题。 The first click will go fine, and the event is handled alright, but the second click, whether it be on the same button or a different button, causes a segfault.第一次点击会顺利,事件处理正常,但是第二次点击,无论是在同一个按钮上还是在不同的按钮上,都会导致段错误。 I'm using Code::Blocks as my IDE on Ubuntu Linux.我在 Ubuntu Linux 上使用 Code::Blocks 作为我的 IDE。 Here's my code for reference:这是我的代码供参考:

main.cpp主程序

/***************************************************************
 * Name:      assignment7Main.cpp
 * Purpose:   Code for Application Frame
 * Author:    Nico ()
 * Created:   2020-03-05
 * Copyright: Nico ()
 * License:
 **************************************************************/

#include "wx_pch.h"
#include "assignment7Main.h"
#include <wx/msgdlg.h>
#include "wx/file.h"
#include "wx/url.h"
#include <fstream>

//(*InternalHeaders(assignment7Frame)
#include <wx/intl.h>
#include <wx/string.h>
//*)

//helper functions
enum wxbuildinfoformat {
    short_f, long_f };

wxString wxbuildinfo(wxbuildinfoformat format)
{
    wxString wxbuild(wxVERSION_STRING);

    if (format == long_f )
    {
#if defined(__WXMSW__)
        wxbuild << _T("-Windows");
#elif defined(__UNIX__)
        wxbuild << _T("-Linux");
#endif

#if wxUSE_UNICODE
        wxbuild << _T("-Unicode build");
#else
        wxbuild << _T("-ANSI build");
#endif // wxUSE_UNICODE
    }

    return wxbuild;
}

//(*IdInit(assignment7Frame)
const long assignment7Frame::ID_BUTTON1 = wxNewId();
const long assignment7Frame::ID_TEXTCTRL1 = wxNewId();
const long assignment7Frame::ID_BUTTON3 = wxNewId();
const long assignment7Frame::ID_TEXTCTRL2 = wxNewId();
const long assignment7Frame::ID_BUTTON2 = wxNewId();
const long assignment7Frame::ID_LISTBOX1 = wxNewId();
const long assignment7Frame::ID_GAUGE1 = wxNewId();
const long assignment7Frame::ID_PANEL1 = wxNewId();
const long assignment7Frame::idMenuQuit = wxNewId();
const long assignment7Frame::idMenuAbout = wxNewId();
const long assignment7Frame::ID_STATUSBAR1 = wxNewId();
//*)

BEGIN_EVENT_TABLE(assignment7Frame,wxFrame)
    //(*EventTable(assignment7Frame)
    //*)
END_EVENT_TABLE()

assignment7Frame::assignment7Frame(wxWindow* parent,wxWindowID id)
{
    //(*Initialize(assignment7Frame)
    wxBoxSizer* BoxSizer1;
    wxBoxSizer* BoxSizer2;
    wxBoxSizer* BoxSizer3;
    wxBoxSizer* BoxSizer4;
    wxBoxSizer* BoxSizer5;
    wxBoxSizer* BoxSizer6;
    wxBoxSizer* BoxSizer7;
    wxFlexGridSizer* FlexGridSizer1;
    wxFlexGridSizer* FlexGridSizer2;
    wxMenu* Menu1;
    wxMenu* Menu2;
    wxMenuBar* MenuBar1;
    wxMenuItem* MenuItem1;
    wxMenuItem* MenuItem2;
    wxStaticBoxSizer* StaticBoxSizer2;

    Create(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, _T("wxID_ANY"));
    BoxSizer1 = new wxBoxSizer(wxHORIZONTAL);
    MainPanel = new wxPanel(this, ID_PANEL1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _T("ID_PANEL1"));
    FlexGridSizer1 = new wxFlexGridSizer(4, 1, 0, 0);
    FlexGridSizer2 = new wxFlexGridSizer(2, 2, 0, 0);
    BoxSizer2 = new wxBoxSizer(wxHORIZONTAL);
    URLButton = new wxButton(MainPanel, ID_BUTTON1, _("Select URL File"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON1"));
    BoxSizer2->Add(URLButton, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    FlexGridSizer2->Add(BoxSizer2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    BoxSizer3 = new wxBoxSizer(wxHORIZONTAL);
    URLText = new wxTextCtrl(MainPanel, ID_TEXTCTRL1, _("Text"), wxDefaultPosition, wxSize(400,25), 0, wxDefaultValidator, _T("ID_TEXTCTRL1"));
    BoxSizer3->Add(URLText, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    FlexGridSizer2->Add(BoxSizer3, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    BoxSizer4 = new wxBoxSizer(wxHORIZONTAL);
    WordButton = new wxButton(MainPanel, ID_BUTTON3, _("Select Word FIle"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON3"));
    BoxSizer4->Add(WordButton, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    FlexGridSizer2->Add(BoxSizer4, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    BoxSizer5 = new wxBoxSizer(wxHORIZONTAL);
    WordText = new wxTextCtrl(MainPanel, ID_TEXTCTRL2, _("Text"), wxDefaultPosition, wxSize(400,25), 0, wxDefaultValidator, _T("ID_TEXTCTRL2"));
    BoxSizer5->Add(WordText, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    FlexGridSizer2->Add(BoxSizer5, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    FlexGridSizer1->Add(FlexGridSizer2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    BoxSizer6 = new wxBoxSizer(wxHORIZONTAL);
    GoButton = new wxButton(MainPanel, ID_BUTTON2, _("Go"), wxDefaultPosition, wxSize(100,30), 0, wxDefaultValidator, _T("ID_BUTTON2"));
    BoxSizer6->Add(GoButton, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    FlexGridSizer1->Add(BoxSizer6, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    StaticBoxSizer2 = new wxStaticBoxSizer(wxHORIZONTAL, MainPanel, _("Top URLs"));
    URLList = new wxListBox(MainPanel, ID_LISTBOX1, wxDefaultPosition, wxSize(600,300), 0, 0, wxVSCROLL, wxDefaultValidator, _T("ID_LISTBOX1"));
    StaticBoxSizer2->Add(URLList, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    FlexGridSizer1->Add(StaticBoxSizer2, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    BoxSizer7 = new wxBoxSizer(wxHORIZONTAL);
    ProgressGauge = new wxGauge(MainPanel, ID_GAUGE1, 100, wxDefaultPosition, wxSize(600,25), 0, wxDefaultValidator, _T("ID_GAUGE1"));
    BoxSizer7->Add(ProgressGauge, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    FlexGridSizer1->Add(BoxSizer7, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    MainPanel->SetSizer(FlexGridSizer1);
    FlexGridSizer1->Fit(MainPanel);
    FlexGridSizer1->SetSizeHints(MainPanel);
    BoxSizer1->Add(MainPanel, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
    SetSizer(BoxSizer1);
    MenuBar1 = new wxMenuBar();
    Menu1 = new wxMenu();
    MenuItem1 = new wxMenuItem(Menu1, idMenuQuit, _("Quit\tAlt-F4"), _("Quit the application"), wxITEM_NORMAL);
    Menu1->Append(MenuItem1);
    MenuBar1->Append(Menu1, _("&File"));
    Menu2 = new wxMenu();
    MenuItem2 = new wxMenuItem(Menu2, idMenuAbout, _("About\tF1"), _("Show info about this application"), wxITEM_NORMAL);
    Menu2->Append(MenuItem2);
    MenuBar1->Append(Menu2, _("Help"));
    SetMenuBar(MenuBar1);
    StatusBar1 = new wxStatusBar(this, ID_STATUSBAR1, 0, _T("ID_STATUSBAR1"));
    int __wxStatusBarWidths_1[1] = { -1 };
    int __wxStatusBarStyles_1[1] = { wxSB_NORMAL };
    StatusBar1->SetFieldsCount(1,__wxStatusBarWidths_1);
    StatusBar1->SetStatusStyles(1,__wxStatusBarStyles_1);
    SetStatusBar(StatusBar1);
    BoxSizer1->Fit(this);
    BoxSizer1->SetSizeHints(this);

    Connect(ID_BUTTON1,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&assignment7Frame::OnURLButtonClick);
    Connect(ID_BUTTON3,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&assignment7Frame::OnWordButtonClick);
    Connect(ID_BUTTON2,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&assignment7Frame::OnGoButtonClick);
    Connect(idMenuQuit,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&assignment7Frame::OnQuit);
    Connect(idMenuAbout,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&assignment7Frame::OnAbout);
    //*)

    URLText->ChangeValue("");
    WordText->ChangeValue("");

    URLChosen = 0;
    WordChosen = 0;
}

assignment7Frame::~assignment7Frame()
{
    //(*Destroy(assignment7Frame)
    //*)
}

void assignment7Frame::OnQuit(wxCommandEvent& event)
{
    Close();
}

void assignment7Frame::OnAbout(wxCommandEvent& event)
{
    wxString msg = wxbuildinfo(long_f);
    wxMessageBox(msg, _("Welcome to..."));
}

void assignment7Frame::OnURLButtonClick(wxCommandEvent& event)
{
    if (URLChosen) {
        for (int i = 0; i < urlsCnt; i++)
            delete[] urls[i];
    }

    wxFileDialog dlg(this, wxT("Open .txt file containing URLs"), "", "", "Data files (*.txt)|*.txt", wxFD_OPEN | wxFD_FILE_MUST_EXIST);

    if (dlg.ShowModal() == wxID_OK) {
        wxFile urlFile(dlg.GetPath(), wxFile::read);

        URLText->ChangeValue(dlg.GetPath());

        if (urlFile.IsOpened()) {
            //read file to filestring
            urlFile.ReadAll(urlFileStringPtr);
            urlFile.Close();
        }
    }
    else
        return;

    std::string s = urlFileString.ToStdString();
    urlsCnt = 0;

    char * temp = new char[s.size() + 1];
    std::copy(s.begin(), s.end(), temp);
    temp[s.size()] = '\0'; // don't forget the terminating 0

    for (int i = 0, j = 0; i < strlen(temp); i++) {
        if (s[i] == '\n') {
            urls[urlsCnt] = new char[i - j + 1];

            for (int x = 0; x < i - j; x++)
                urls[urlsCnt][x] = temp[j+x];

            urls[urlsCnt][i-j-1] = '\0';

            urlsCnt++;
            j = i;
        }
    }

    URLChosen = 1;
}

void assignment7Frame::OnWordButtonClick(wxCommandEvent& event)
{
    if (WordChosen) {
        for (int i = 0; i < wordsCnt; i++)
            delete[] words[i];
    }

    wxFileDialog dlg(this, wxT("Open .txt file containing target words"), "", "", "Data files (*.txt)|*.txt", wxFD_OPEN | wxFD_FILE_MUST_EXIST);

    if (dlg.ShowModal() == wxID_OK) {
        wxFile wordFile(dlg.GetPath(), wxFile::read);

        WordText->ChangeValue(dlg.GetPath());

        if (wordFile.IsOpened()) {
            wordFile.ReadAll(wordFileStringPtr);
            wordFile.Close();
        }
    }
    else
        return;

    std::string s = wordFileString.ToStdString();
    wordsCnt = 0;

    char * temp = new char[s.size() + 1];
    std::copy(s.begin(), s.end(), temp);
    temp[s.size()] = '\0'; // don't forget the terminating 0

    for (int i = 0, j = 0; i < strlen(temp); i++) {
        if (s[i] == '\n') {
            words[wordsCnt] = new char[i - j + 1];

            for (int x = 0; x < i - j; x++)
                words[wordsCnt][x] = temp[j+x];

            words[wordsCnt][i-j-1] = '\0';

            wordsCnt++;
            j = i;
        }
    }

    WordChosen = 1;
}

void assignment7Frame::OnGoButtonClick(wxCommandEvent& event)
{
    if (URLChosen && WordChosen) {
        ProgressGauge->SetValue(33);
        wxURL url(urls[0]);

        if (url.GetError() == wxURL_NOERR) {
            wxInputStream *in_stream;
            in_stream = url.GetInputStream();
        }
        else {
            wxString msg("not working");
            wxMessageBox(msg, _("PROCESSING ERROR"));
        }
    }
    else {
        wxString msg("Error, can't process without both URL file and word file chosen. Please choose file.");
        wxMessageBox(msg, _("PROCESSING ERROR"));
    }
}

main.h主文件

/***************************************************************
 * Name:      assignment7Main.h
 * Purpose:   Defines Application Frame
 * Author:    Nico ()
 * Created:   2020-03-05
 * Copyright: Nico ()
 * License:
 **************************************************************/

#ifndef ASSIGNMENT7MAIN_H
#define ASSIGNMENT7MAIN_H

//(*Headers(assignment7Frame)
#include <wx/button.h>
#include <wx/frame.h>
#include <wx/gauge.h>
#include <wx/listbox.h>
#include <wx/menu.h>
#include <wx/panel.h>
#include <wx/sizer.h>
#include <wx/statusbr.h>
#include <wx/textctrl.h>
//*)

#include <string>

//using namespace std;

class assignment7Frame: public wxFrame
{
    public:

        assignment7Frame(wxWindow* parent,wxWindowID id = -1);
        virtual ~assignment7Frame();

    private:

        //(*Handlers(assignment7Frame)
        void OnQuit(wxCommandEvent& event);
        void OnAbout(wxCommandEvent& event);
        void OnURLButtonClick(wxCommandEvent& event);
        void OnWordButtonClick(wxCommandEvent& event);
        void OnGoButtonClick(wxCommandEvent& event);
        //*)

        //(*Identifiers(assignment7Frame)
        static const long ID_BUTTON1;
        static const long ID_TEXTCTRL1;
        static const long ID_BUTTON3;
        static const long ID_TEXTCTRL2;
        static const long ID_BUTTON2;
        static const long ID_LISTBOX1;
        static const long ID_GAUGE1;
        static const long ID_PANEL1;
        static const long idMenuQuit;
        static const long idMenuAbout;
        static const long ID_STATUSBAR1;
        //*)

        //(*Declarations(assignment7Frame)
        wxButton* GoButton;
        wxButton* URLButton;
        wxButton* WordButton;
        wxGauge* ProgressGauge;
        wxListBox* URLList;
        wxPanel* MainPanel;
        wxStatusBar* StatusBar1;
        wxTextCtrl* URLText;
        wxTextCtrl* WordText;
        //*)

        wxString urlFileString;
        wxString * urlFileStringPtr = &urlFileString;

        wxString wordFileString;
        wxString * wordFileStringPtr = &wordFileString;

        int URLChosen;
        int WordChosen;

        int urlsCnt;
        int wordsCnt;

        char * urls[];
        char * words[];

        DECLARE_EVENT_TABLE()
};

#endif // ASSIGNMENT7MAIN_H

debugger info调试器信息

Active debugger config: GDB/CDB debugger:Default
Building to ensure sources are up-to-date
Selecting target: 
Debug
Adding source dir: /home/dawbuntu/GUI/assignment7/
Adding source dir: /home/dawbuntu/GUI/assignment7/
Adding file: /home/dawbuntu/GUI/assignment7/bin/Debug/assignment7
Changing directory to: /home/dawbuntu/GUI/assignment7/.
Set variable: LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu:
Starting debugger: /usr/bin/gdb -nx -fullname -quiet  -args /home/dawbuntu/GUI/assignment7/bin/Debug/assignment7
done
Setting breakpoints
Debugger name and version: GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
Child process PID: 5677
In gtk_widget_style_get_valist () (/usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0)
#23 0x000055555556b0e1 in assignment7Frame::OnWordButtonClick (this=0x555555888dd0, event=...) at /home/dawbuntu/GUI/assignment7/assignment7Main.cpp:229
/home/dawbuntu/GUI/assignment7/assignment7Main.cpp:229:8826:beg:0x55555556b0e1
At /home/dawbuntu/GUI/assignment7/assignment7Main.cpp:229
Continuing...
Program terminated with signal SIGSEGV, Segmentation fault.
Debugger finished with status 0

picture of GUI GUI pic one GUI pic two图形界面图形界面图形一图形界面图形二

The program keeps crashing and segfaulting whenever the second event is triggered, wherever that is.无论何时触发第二个事件,该程序都会不断崩溃和段错误。 I'm guessing it's wxSmith and Code::Block's automatic generation of code for the GUI, but I'm unsure since I'm fairly new to wxWidgets.我猜是 wxSmith 和 Code::Block 为 GUI 自动生成代码,但我不确定,因为我对 wxWidgets 还很陌生。 Help much appreciated.非常感谢帮助。

This is the problem:这就是问题:

char * urls[];
char * words[];

These are called "flexible array members" and they are not valid in C++ .这些被称为“灵活数组成员”,它们在 C++ 中无效

Try to use something like:尝试使用类似的东西:

std::vector<std::string> urls;
std::vector<std::string> words;

instead.反而。 Obviously you would need to adjust the rest of the code to use the new datatypes for urls and words.显然,您需要调整其余代码以使用新的 url 和 word 数据类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM