代码之家  ›  专栏  ›  技术社区  ›  Arun

C++ STD::向量插入段错误

  •  2
  • Arun  · 技术社区  · 14 年前

    我正在写一个测试程序来理解 vector 好多了。在其中一个场景中,我试图 insert 在指定位置输入向量的值。代码编译得很干净。但是,在执行时,它会从 v8.insert(..) 行(见下面的代码)。我很困惑。有人能指出我的代码有什么问题吗?

    #define UNIT_TEST(x) assert(x)
    #define ENSURE(x) assert(x)
    
    #include <vector>
    typedef std::vector< int >                     intVector;
    typedef std::vector< int >::iterator           intVectorIterator;
    typedef std::vector< int >::const_iterator     intVectorConstIterator;
    
    
    intVectorIterator find( intVector v, int key );
    void test_insert();
    
    intVectorIterator
    find( intVector v, int key )
    {
        for( intVectorIterator it = v.begin(); it != v.end(); ++it )
        {
            if( *it == key )
            {
                return it;
            }
        }
    
        return v.end();
    }
    
    void
    test_insert()
    {
        const int values[] = {10, 20, 30, 40, 50};
        const size_t valuesLength = sizeof( values ) / sizeof( values[ 0 ] );
        size_t index = 0;
        const int insertValue = 5;
    
        intVector v8;
        for( index = 0; index < valuesLength; ++index )
        {
            v8.push_back( values[ index ] );
        }
    
        ENSURE( v8.size() == valuesLength );
        for( index = 0; index < valuesLength; ++index )
        {
            printf( "index = %u\n", index );
    
            intVectorIterator it = find( v8, values[ index ] );
            ENSURE( it != v8.end() );
            ENSURE( *it == values[ index ] );
    
            // intVectorIterator itToInsertedItem = 
            v8.insert( it, insertValue );                      // line 51
            // UNIT_TEST( *itToInsertedItem == insertValue );
        }
    }
    
    int main()
    {
        test_insert();
        return 0;
    }
    
    $ ./a.out
    index = 0
    Segmentation Fault (core dumped)
    
    (gdb) bt
    #0  0xff3a03ec in memmove () from /platform/SUNW,T5140/lib/libc_psr.so.1
    #1  0x00012064 in std::__copy_move_backward<false, true, std::random_access_iterator_tag>::__copy_move_b<int> (__first=0x23e48, __last=0x23450, __result=0x23454)
        at /local/gcc/4.4.1/lib/gcc/sparc-sun-solaris2.10/4.4.1/../../../../include/c++/4.4.1/bits/stl_algobase.h:575
    #2  0x00011f08 in std::__copy_move_backward_a<false, int*, int*> (__first=0x23e48, __last=0x23450, __result=0x23454)
        at /local/gcc/4.4.1/lib/gcc/sparc-sun-solaris2.10/4.4.1/../../../../include/c++/4.4.1/bits/stl_algobase.h:595
    #3  0x00011d00 in std::__copy_move_backward_a2<false, int*, int*> (__first=0x23e48, __last=0x23450, __result=0x23454)
        at /local/gcc/4.4.1/lib/gcc/sparc-sun-solaris2.10/4.4.1/../../../../include/c++/4.4.1/bits/stl_algobase.h:605
    #4  0x000119b8 in std::copy_backward<int*, int*> (__first=0x23e48, __last=0x23450, __result=0x23454) at /local/gcc/4.4.1/lib/gcc/sparc-sun-solaris2.10/4.4.1/../../../../include/c++/4.4.1/bits/stl_algobase.h:640
    #5  0x000113ac in std::vector<int, std::allocator<int> >::_M_insert_aux (this=0xffbfeba0, __position=..., __x=@0xffbfebac)
        at /local/gcc/4.4.1/lib/gcc/sparc-sun-solaris2.10/4.4.1/../../../../include/c++/4.4.1/bits/vector.tcc:308
    #6  0x00011120 in std::vector<int, std::allocator<int> >::insert (this=0xffbfeba0, __position=..., __x=@0xffbfebac)
        at /local/gcc/4.4.1/lib/gcc/sparc-sun-solaris2.10/4.4.1/../../../../include/c++/4.4.1/bits/vector.tcc:126
    #7  0x00010bc0 in test_insert () at vector_insert_test.cpp:51
    #8  0x00010c48 in main () at vector_insert_test.cpp:58
    (gdb) q
    
    2 回复  |  直到 14 年前
        1
  •  8
  •   Michael Kristofik    14 年前

    你正在通过 v8 按价值 find 功能。因此,返回的迭代器指向向量的副本,该副本在find调用返回后超出范围。尝试传递(const)引用,或者更好地说,只需使用 std::find .

        2
  •  2
  •   Karmastan    14 年前

    因为缺少两个标点符号,程序被中断。:)

    如前所述,当您调用自己的find()版本时,会生成一个intvector副本,该副本由函数使用。当find()返回迭代器时,它是 复制 而不是V8。所以当你用另一个向量的迭代器调用v8.insert()时,它当然会中断。

    您要查找的解决方案通过引用find()传递IntVector。(即添加两个“&”字符)

    更好的解决方案只是重用std::find()。