C++ vector 和 Gtkmm 能完美地协同工作吗?从 gtkmm on_click 方法获取向量<string> 的值时出现分段错误

Posted

技术标签:

【中文标题】C++ vector 和 Gtkmm 能完美地协同工作吗?从 gtkmm on_click 方法获取向量<string> 的值时出现分段错误【英文标题】:Do C++ vector and Gtkmm work together perfectly?. Segmentation fault when getting values of vector<string> from gtkmm on_click method 【发布时间】:2018-04-18 20:22:57 【问题描述】:

我正在使用 gtkmm 和 C++ 为我的项目创建树视图。 我想做的是从我的 order 类中获取变量属性。我选择使用向量来存储这些属性,因此我可以通过在不同的类(例如我的 ma​​in_window 类)中调用该方法来轻松获取它们。除了显示分段错误的 ma​​in_window 类之外,我可以成功地从其他类中获取所有值。

运行我的程序: 1/ 在终端输入“make” 2/输入“./mice”运行程序 3/点击文件->测试。程序崩溃

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

来自 emporium 的 auto_add 方法。 cp

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、order、controller 类中的向量方法。

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;    

但是为了代码的正确性,请记住在Emporium类析构函数中删除std::vector&lt;Order*&gt; orders中的订单。

【讨论】:

那么请告诉我应该怎么做才能防止这种崩溃?谢谢!我试过使用 Order *order0 = new Order (1);但它仍然不起作用。

以上是关于C++ vector 和 Gtkmm 能完美地协同工作吗?从 gtkmm on_click 方法获取向量<string> 的值时出现分段错误的主要内容,如果未能解决你的问题,请参考以下文章

gtkmm 程序的外观不佳

关于 glade3 和 gtkmm 的 Linux / C++ 帮助

C++ 向量排序简单地说

在 Eclipse 中为 C++ 设置 GTKmm

将 C 中的 gtk3 与 C++ 中的 gtkmm 结合起来

C++ 中带有 Gtkmm 的 ProgressBar