std :: set :: insert()分段错误

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了std :: set :: insert()分段错误相关的知识,希望对你有一定的参考价值。

我通过插入std :: set得到了SEG Fault。

使用gcc进行编译时,它可以正常工作,但是对于应用程序的另一部分需要的qtCreator,它会在std内部呈现分段错误。

班级负责人:

class Transceiver{
 ...
std::set<Inbox*> receivers [256];
};

初始化:

Transceiver::Transceiver(...)
{
    ...
    for(int i = 0 ; i < 256 ; i++)
    {
        receivers[i] = std::set<Inbox*>();
        receivers[i].clear();
    }
    ...
}

在这里使用:

void Transceiver::addreceiver(Inbox& i , uint8_t id)
{
    receivers[id].insert(&i);
}

gdb backtrace :(从#4开始)

Thread 1 "ControllGUI" received signal SIGSEGV, Segmentation fault.
0x0005e2b4 in std::less<Inbox*>::operator() (this=0x660c0, __x=@0x7effe154: 0x433550, __y=<error reading variable>)
    at /usr/include/c++/6/bits/stl_function.h:386
386       { return __x < __y; }
(gdb) bt
#0  0x0005e2b4 in std::less<Inbox*>::operator() (this=0x660c0, __x=@0x7effe154: 0x433550, __y=<error reading variable>)
    at /usr/include/c++/6/bits/stl_function.h:386
#1  0x0005e3cc in std::_Rb_tree<Inbox*, Inbox*, std::_Identity<Inbox*>, std::less<Inbox*>, std::allocator<Inbox*> >::_M_get_insert_unique_pos
    (this=0x660c0, __k=@0x7effe154: 0x433550) at /usr/include/c++/6/bits/stl_tree.h:1836
#2  0x0005cd5c in std::_Rb_tree<Inbox*, Inbox*, std::_Identity<Inbox*>, std::less<Inbox*>, std::allocator<Inbox*> >::_M_insert_unique<Inbox*>(Inbox*&&) (this=0x660c0, 
    __v=<unknown type in /home/pi/DT_WS1718_02_StarCar/pi/GUI/build-ControllGUI-Desktop-Debug/ControllGUI, CU 0x284fbc, DIE 0x29c590>)
    at /usr/include/c++/6/bits/stl_tree.h:1889
#3  0x0005bab0 in std::set<Inbox*, std::less<Inbox*>, std::allocator<Inbox*> >::insert(Inbox*&&) (this=0x660c0, 
    __x=<unknown type in /home/pi/DT_WS1718_02_StarCar/pi/GUI/build-ControllGUI-Desktop-Debug/ControllGUI, CU 0x284fbc, DIE 0x29af30>)
    at /usr/include/c++/6/bits/stl_set.h:492
#4  0x00059f5c in Transceiver::addreceiver (this=0x64f94, i=..., id=180 '264') at ../../IBP/IBC_Transceiver.cpp:160
#5  0x00028788 in Inbox::listen (this=0x433550, id=180 '264') at ../../IBP/IBC_Inbox.cpp:98
#6  0x000253b0 in SensorValuesWidget::SensorValuesWidget (this=0x484000, parent=0x7effee1c, alertThread=0x2411c0, pButtonGoBackText=..., 
    IBCPointer=0x64d94 <__libc_csu_init+76>) at ../ControllGUI/sensorvalueswidget.cpp:16
#7  0x0001b4bc in HomeWindow::showSensorValuesWidgetAfterControlMode (this=0x7effee1c) at ../ControllGUI/homewindow.cpp:132
#8  0x00061b64 in HomeWindow::qt_static_metacall (_o=0x7effee1c, _c=QMetaObject::InvokeMetaMethod, _id=8, _a=0x7effe288)
    at moc_homewindow.cpp:107
#9  0x76470524 in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib/arm-linux-gnueabihf/libQt5Core.so.5
#10 0x0006470c in ControllerControlModeWidget::showsensorvalueswidget (this=0x40b728) at moc_controllercontrolmodewidget.cpp:170
#11 0x00024d0c in ControllerControlModeWidget::slotShowSensorValues (this=0x40b728) at ../ControllGUI/controllercontrolmodewidget.cpp:169
#12 0x00064348 in ControllerControlModeWidget::qt_static_metacall (_o=0x40b728, _c=QMetaObject::InvokeMetaMethod, _id=6, _a=0x7effe3f4)
    at moc_controllercontrolmodewidget.cpp:101

在segfault显示之前的最后一次调用的qtCreator Debugger __y中

有什么不对?在调用之前这些集是空的,我仍然看到std调用的比较。另外(阅读关于此的其他问题)指针默认是可比较的。

编辑:找到答案中描述的问题来源。

答案

最后,它是一个同事用户创建一个Transceiver的对象,但将错误的指针传递给使用它的代码,导致未定义的行为。它导致它在我提供的代码中失败,就像gdb输出所示,所以它在我脑海中。 所以有一些要记住的要点:

  • 未定义的行为甚至错误的位置是未定义的
  • 相信你的考试
另一答案

std::set<Inbox*> receivers [256]

你在这里做的是创建一组256组收件箱指针。如果这真的是你想要的,那么我建议你作为第一步清理你坚持使用C ++并使用std::vectorstd::array(C ++ 11及以上版本)代替:

std::vector<std::set<Inbox*>> receivers;

std::array<std::set<Inbox*>, 256> receivers;

当您调整代码以匹配该更改时,我几乎可以预期问题的根源会显现出来......

作为一般规则,如果有可能don't use C-style arrays in C++

以上是关于std :: set :: insert()分段错误的主要内容,如果未能解决你的问题,请参考以下文章

linux C++获取两个std::set容器差异(容器元素差异)(容器元素差别)std::set_differencestd::inserter

linux C++获取两个std::set容器差异(容器元素差异)(容器元素差别)std::set_differencestd::inserter

C++ std::set insert 怎么得到 返回值 是什么

使用模板调用 std::less<int>::operator() 导致分段错误

使用 std::set 并保留输入顺序

带有 std::promise 的 C++11 分段错误