Вектор C++ и Gtkmm прекрасно работают вместе? Ошибка сегментации при получении значений вектора<string> из метода gtkmm on_click

Я нахожусь в середине создания дерева для моего проекта с использованием gtkmm и C++. То, что я хочу сделать, это получить свойства переменной из моего класса заказа. И я решил использовать vector для хранения этих свойств, чтобы легко получить их, вызывая этот метод в другом классе, например, в классе main_window. Я могу успешно получить все значения из других классов, кроме класса main_window, показывающего ошибку сегментации.

Чтобы запустить мою программу: 1/ введите "make" в терминале 2/ введите "./mice", чтобы запустить программу 3/ нажмите file->test. Вылетает программа

Класс main_window.cpp:

void Main_window::on_test_click() {
std::cout<< " On _test_clicked\n";
//auto add 1 order
controller.execute_cmd(99);
 //THE LINE BELOW IS NOT WORKING IN ON_TEST_CLICK
std::vector<std::string> record = controller.order_to_strings(0);

}

метод auto_add из emporium. CPP

void Emporium::auto_add() {
  Order order0(1);
  add_order(&order0);  
  std::vector<std::string> record = order_to_strings(0);
  std::cout << "This is printing from emporium.cpp class" <<std::endl 
            << "Id:" << record[0] <<"State: "<< record[1]<<"Price:"<< record[2]<< std::endl;    
}

векторные методы в emporium, порядок, классы контроллеров.

std::vector<std::string> Controller::order_to_strings(int index) {
   emporium.order_to_strings(index);
}
std::vector<std::string> Emporium::order_to_strings(int index) { 
      return orders[index]->to_strings();
     }
std::vector<std::string> Order::to_strings(){
  std::vector<std::string> order;
  order.push_back(std::to_string(id_number));
  order.push_back(state.to_string());
  order.push_back(std::to_string(price));
  return order;
}

Ошибка:

    *** Error in `./mice': free(): invalid pointer: 0x00007fa77a295000 ***
    ======= Backtrace: =========
    /lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7fa77d63a7e5]
    /lib/x86_64-linux-gnu/libc.so.6(+0x8037a)[0x7fa77d64337a]
    /lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7fa77d64753c]
    ./mice[0x406793]
    ./mice[0x4065cf]
    ./mice[0x40630a]
    ./mice[0x405eb7]
    ./mice(_ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EED1Ev+0x35)[0x405b03]
 ......

Это моя полная версия моего проекта. Тестовая папка - это моя упрощенная версия: https://github.com/dtn9797/MICE/tree/master/test

1 ответ

В методе auto_add(), Order объект создан, который уничтожается в конце auto_add() метод. Однако в то же время указатель на этот объект добавляется в вектор orders, Этот указатель указывает на недопустимые данные в памяти за пределами auto_add() метод. Доступ к данным за этим указателем дает сбой.

void Emporium::auto_add() {
  Order order0(1); //creating order0 local variable
  add_order(&order0);  //here pointer to something that will be destroyed soon is stored
  std::vector<std::string> record = order_to_strings(0);
  std::cout << "This is printing from emporium.cpp class" <<std::endl 
            << "Id:" << record[0] <<"State: "<< record[1]<<"Price:"<< record[2]<< std::endl;    
} //order0 local variable is destroyed here

void Emporium::add_order (Order* order) {
  orders.push_back(order);
}

Одно из возможных решений по предотвращению сбоев, которое вы можете создать Order объект как это:

void Emporium::auto_add() {
  add_order(new Order(1));
  std::vector<std::string> record = order_to_strings(0);
  std::cout << "This is printing from emporium.cpp class" <<std::endl 
            << "Id:" << record[0] <<"State: "<< record[1]<<"Price:"<< record[2]<< std::endl;    
}

Но для правильности кода не забудьте удалить заказы, которые находятся в std::vector<Order*> orders в Emporium класс деструктор.

Другие вопросы по тегам