调用控制器函数时带有 MVC 错误代码 SIGSEGV 的 wxWidgets

wxWidgets with MVC Error code SIGSEGV when calling controller function


我将 wxWidgets 与 MVC 模式一起使用,当我在视图中调用控制器函数时遇到问题
compareRGB(...),compareALPHA(...) and compareHSV(...)

用于比较具有公差的两个图像。
基本上当调用函数时程序崩溃并出现代码错误

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

我已经尝试了所有解决方案,但错误仍然存​​在。

此时该函数仅在终端上打印一个字。
这是导致错误的代码(其他功能完美运行):

void View::compareImages(wxCommandEvent &event){

    int imagesActive = imagesActivatedCount();
    wxString mode = getMode();
    double tolerance = colorToleranceSlider->GetValue();
    if(imagesActive < 2){
        wxMessageBox(_("SELEZIONARE DUE IMMAGINI DA COMPARARE"),_("ERRORE"),wxOK | wxICON_EXCLAMATION);
    }
    else if(mode.IsSameAs(_("RGB"))){
        wxString pathImage1 = *activeImages;
        wxString pathImage2 = *(activeImages + 1);
        controller.compareRGB(pathImage1,pathImage2,tolerance);

    }
    else if(mode.IsSameAs(_("HSV"))){
        wxString pathImage1 = *activeImages;
        wxString pathImage2 = *(activeImages + 1);
        controller.compareHSV(pathImage1,pathImage2,tolerance);
    }
    else if(mode.IsSameAs(_("ALPHA"))){
        wxString pathImage1 = *activeImages;
        wxString pathImage2 = *(activeImages + 1);
        controller.compareAlpha(pathImage1,pathImage2,tolerance);
    }
    else{
        wxMessageBox(_("SCEGLIERE METODO DI COMPARAZIONE"),_("ERRORE"),wxOK | wxICON_EXCLAMATION);
    }
}

完整来源:
#include "View.h"
enum{
    PANEL_ID,
    BUTTON_ADD,
    BUTTON_REMOVE,
    BUTTON_ACTIVATE,
    BUTTON_COMPARE,
    SLIDER_COLOR,
    MODE_SELECTOR,
    LIST_ID,
    ABOUT,
    STATIC_ID,
    VALUE_SLIDER
};
/*Event table of the view*/
wxBEGIN_EVENT_TABLE(View,wxFrame)
    EVT_BUTTON(BUTTON_ADD,View::loadImages)
    EVT_BUTTON(BUTTON_REMOVE,View::removeImages)
    EVT_BUTTON(BUTTON_ACTIVATE,View::activateSelectedImages)
    EVT_BUTTON(BUTTON_COMPARE,View::compareImages)
    EVT_BUTTON(BUTTON_ACTIVATE,View::activateSelectedImages)
    EVT_MENU(ABOUT,View::onAbout)
    EVT_MENU(wxID_EXIT,View::onExit)
    EVT_SLIDER(SLIDER_COLOR,View::onSliderUpdate)
wxEND_EVENT_TABLE()


View::View(const std::string title, const wxPoint &pos, const wxSize &size, AbstractModel& model, AbstractController& c):model(model),controller(c) ,wxFrame(NULL,wxID_ANY,title,pos,size) {
    model.registerObserver(this);  //registration view for successive notification
    //View implementation
}
void View::update(int eventCode) {

}
/*Delete the selected images
 * the while cicle it afflict only the image selected*/
void View::removeImages(wxCommandEvent& event){
    long item;
    while((item = list->GetNextItem(-1,wxLIST_NEXT_ALL,wxLIST_STATE_SELECTED)) != -1){
        list->DeleteItem(item);
    }
}
/*load images on storage
 * It load the paths in the list view but in the model there is a map that associate
 * the wxImage object with his relative path*/
void View::loadImages(wxCommandEvent& event){
    wxFileDialog* fileDialog=new wxFileDialog(this, _("Scegli una o più foto"),wxEmptyString,wxEmptyString,wxFileSelectorDefaultWildcardStr,wxFD_MULTIPLE);
    if(fileDialog->ShowModal() == wxID_CANCEL){
        return;
    }
    wxArrayString paths;
    fileDialog->GetPaths(paths);
    try {
        for (auto iterator = paths.begin(); iterator < paths.end(); ++iterator) {
            list->InsertItem(0,*iterator);
        }

    }
    catch (std::exception& error) {
        std::cout << "Caught exception: " << error.what() << std::endl;
    }
}
int View::imagesActivatedCount() {
    int count = 0;
    long item = -1;
    while((item = list->GetNextItem(item,wxLIST_NEXT_ALL,wxLIST_STATE_DONTCARE)) != -1){
        if (list->GetItemText(item,1).IsSameAs(_("*")))
        {
            count++;
        }
    }
    return count;
}
/*Deselect the activated images
 * this function is called on activatedSelectImages function for deselect before activate the new images
 * For practical reasons the function scan every row in the list and if in the column next to him is present the "*"
 * symbol it deselect him and clear the activated images array
 */
void View::deselectImages() {
    long item = -1;
    while((item = list->GetNextItem(item,wxLIST_NEXT_ALL,wxLIST_STATE_DONTCARE)) != -1){
        if(list->GetItemText(item,1).IsSameAs(_("*"))){
            list->SetItem(item,1,_(""));
        }
    }
}

void View::activateSelectedImages(wxCommandEvent& event) {
    int imageActive = imagesActivatedCount();
    int itemCount=0;
    long item = -1;
    wxString arr[2];
    if(imageActive >= 2 || list->GetSelectedItemCount() >= 2)
    {
        deselectImages();
        imageActive = 0;
    }
    while((item = list->GetNextItem(item,wxLIST_NEXT_ALL,wxLIST_STATE_SELECTED)) != -1){
        if(itemCount < 2){
            list->SetItem(item,1,_("*"));
            itemCount++;
            imageActive++;
        }
    }
    if (imageActive == 2)
    {
        itemCount = 0;
        item = -1;
        wxString text;
        while((item = list->GetNextItem(item,wxLIST_NEXT_ALL,wxLIST_STATE_DONTCARE)) != -1){
            text = list->GetItemText(item,1);
            if (text.IsSameAs(_("*"))){
                arr[itemCount]=list->GetItemText(item);
                itemCount++;
            }

        }
        activeImages = arr;
        std::cout<< *activeImages << std::endl;
        std::cout << *(activeImages + 1) << std::endl;
    }
}

void View::compareImages(wxCommandEvent &event){

    int imagesActive = imagesActivatedCount();
    wxString mode = getMode();
    double tolerance = colorToleranceSlider->GetValue();
    if(imagesActive < 2){
        wxMessageBox(_("SELEZIONARE DUE IMMAGINI DA COMPARARE"),_("ERRORE"),wxOK | wxICON_EXCLAMATION);
    }
    else if(mode.IsSameAs(_("RGB"))){
        wxString pathImage1 = *activeImages;
        wxString pathImage2 = *(activeImages + 1);
        controller.compareRGB(pathImage1,pathImage2,tolerance);

    }
    else if(mode.IsSameAs(_("HSV"))){
        wxString pathImage1 = *activeImages;
        wxString pathImage2 = *(activeImages + 1);
        controller.compareHSV(pathImage1,pathImage2,tolerance);
    }
    else if(mode.IsSameAs(_("ALPHA"))){
        wxString pathImage1 = *activeImages;
        wxString pathImage2 = *(activeImages + 1);
        controller.compareAlpha(pathImage1,pathImage2,tolerance);
    }
    else{
        wxMessageBox(_("SCEGLIERE METODO DI COMPARAZIONE"),_("ERRORE"),wxOK | wxICON_EXCLAMATION);
    }
}

}

控制器来源:
#include "Controller.h"

Controller::Controller(AbstractModel& model) : model(model){}

void Controller::removeImages(wxArrayString paths) {

    for(int it = 0; it < paths.size();it++){
        model.removeImage(paths[it]);
    }

}

void Controller::loadImages(wxArrayString paths) {

    for(int it = 0; it < paths.size(); it++){
        model.loadImage(paths[it]);
    }
}

void Controller::compareRGB(wxString path1, wxString path2, double tolerance) {
    std::cout<<"A"<<std::endl;
}

void Controller::compareAlpha(wxString path1, wxString path2, double tolerance) {
    std::cout<<"B"<<std::endl;
}

void Controller::compareHSV(wxString path1, wxString path2, double tolerance) {
    std::cout<<"C"<<std::endl;
}

正如您在评论中提到的,

activeImages is a wxString*

所以你有它:activeImages = arr。后者是一个 局部变量 ,它将在 activateSelectedImages() 结束时被释放。稍后在 compareImages() 中使用 activeImages 时,您会得到 未定义的行为