2010-05-10 108 views
2

我正在編寫一個測試程序來理解vector的更好。在其中一種情況下,我試圖將insert的值存入指定位置的向量中。代碼編譯乾淨。但是,在執行時,它會從v8.insert(..)行中引發分段錯誤(請參閱下面的代碼)。我很困惑。有人可以指出我的代碼有什麼問題嗎?C++ std :: vector插入段錯誤

#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=..., [email protected]) 
    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=..., [email protected]) 
    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 
+0

上面的代碼是我計劃編寫的向量單元測試的一個片段。受測試驅動開發哲學影響,我首先寫單元測試!計劃編寫std :: vector(的子集)的原因是目標環境沒有STL。這也是我沒有使用std :: find()的原因。感謝您的答案。 – Arun 2010-05-10 21:44:29

回答

8

你按值傳遞v8find功能。迭代器因此將點返回到查找調用返回後超出範圍的向量副本。嘗試傳遞(const)引用,或者更好,只需使用std::find

+0

感謝您捕捉非常關鍵的錯誤。 – Arun 2010-05-10 21:40:43

2

您的程序因爲缺少兩個標點符號而中斷。 :)

正如你所寫的,當你調用你自己的find()版本時,一個副本是由你的intVector組成的,並且被函數使用。 find()返回一個迭代器時,它是拷貝的迭代器,而不是v8。所以當你使用另一個vector的迭代器調用v8.insert()時,它當然會中斷。

您正在查找的解決方案通過引用find()傳遞intVector。 (即添加兩個'&'字符)

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

+0

感謝您指出錯誤。 – Arun 2010-05-10 21:41:27