wxWidgets с кодом ошибки MVC SIGSEGV при вызове функции контроллера - PullRequest
0 голосов
/ 04 августа 2020

Я использую wxWidgets с шаблоном MVC, и у меня возникают проблемы, когда я вызываю функции контроллера в View
compareRGB(...),compareALPHA(...) and compareHSV(...)

для сравнения двух изображений с допуском.
В основном, когда функции вызываются программой cra sh с ошибкой кода

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;
}

1 Ответ

0 голосов
/ 05 августа 2020

Как вы упомянули в комментарии,

activeImages - это wxString *

Итак, у вас есть: activeImages = arr. Последняя - это локальная переменная , которая будет освобождена в конце activateSelectedImages(). При использовании activeImages позже в compareImages() вы получаете неопределенное поведение .

...