C ++ std :: vector insert segfault

时间:2010-05-10 20:50:51

标签: c++ vector

我正在编写一个测试程序来更好地理解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 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分:2)

您的程序已损坏,因为它缺少两个标点符号。 :)

如上所述,当您调用自己的find()版本时,会复制一个intVector副本,并由该函数使用。当find()返回一个迭代器时,它是 copy 的迭代器,而不是v8的迭代器。所以当你用另一个向量的迭代器调用v8.insert()时,它当然会破坏。

您正在寻找的解决方案通过引用find()传递intVector。 (即添加两个'&amp;'字符)

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