Вектор 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
класс деструктор.