2011-10-21 152 views
2

我認爲下面的代碼片段是完全合法的(它無論如何建立在MS Visual Studio 2008,C++上)。C++傳遞指向向量元素的指針而不是數組指針

我用它鏈接到第三方庫。但是,我想是因爲我傳遞一個指向一個向量元素,而不是一個普通指針的第三方庫函數期望,我得到一個運行時錯誤的C-運行時庫檢測

無效參數

我在這裏做錯了什麼?

std::vector<int> vec_ints(27,0); 
std::vector<double> vec_doub(27, 0.); 
for(int i = 0; i < n; ++i) { 
    //-Based on my understanding when i >=27, STL vectors automatically reallocate additional space (twice). 
    vec_ints[i] = ...; 
    vec_doub[i] = ...;  
} 
const int* int_ptr = &vec_ints[0]; 
const double* doub_ptr = &vec_doub[0]; 
//-Func is the 3rd party library function that expects a const int* and const double* in the last 2 arguments. 
func(...,...,int_ptr,doub_ptr); 

但建立在MS的Visual Studio 2008(Windows Vista中)後運行此,導致運行錯誤如上面提到的,即,

由C運行時庫檢測

參數無效

還沒有在Linux上測試過,我確實希望避免將矢量的內容複製到數組中。任何想法是怎麼回事?

進一步編輯以確認Nick和Chris的推薦使用情況,並繼續與Vlad等人討論;這裏有一個代碼片段:

#include <iostream> 
#include <vector> 

int main() { 
    for(int i=2; i<6; ++i) { 
     int isq = i*i; 
     std::vector<int> v; 
     v.reserve(4); 
     for(int j=0; j<isq; ++j) { 
     v.push_back(j); 
     } 
     std::cout << "Vector v: size = " << v.size() << " capacity = " << v.capacity() 
       << "\n"; 
     std::cout << "Elements: \n"; 
     for(int k=0; k<v.size(); ++k) { 
     std::cout << v.at(k) << " "; 
     } 
     std::cout << "\n\n"; 
    } 
    return 0; 
} 

給出輸出:

Vector v: size = 4 capacity = 4 
Elements: 
0 1 2 3 

Vector v: size = 9 capacity = 16 
Elements: 
0 1 2 3 4 5 6 7 8 

Vector v: size = 16 capacity = 16 
Elements: 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 

Vector v: size = 25 capacity = 32 
Elements: 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 
22 23 24 

所以ATLEAST在此背景下,在使用沒有明確調整大小的使用,似乎意/預期工作。

回答

3

std::vector<T>擴展,如果你使用的是std::vector<T>::push_back(T &)std::vector<T>::insert(iterator, T &)(感謝K-BALLO)或顯式調用std::vector<T>::resize(size_t)添加元素。否則,它不會擴大。

std::vector<int> vec_ints; 
vec_ints.reserve(27); 
std::vector<double> vec_doub; 
vec_doub.reserve(27); 
for(int i = 0; i < n; ++i) { 
    vec_ints.push_back(...); 
    vec_doub.push_back(...);  
} 
const int* int_ptr = &vec_ints[0]; 
const double* doub_ptr = &vec_doub[0]; 
func(...,...,int_ptr,doub_ptr); 

你想這樣的事情

+2

'insert'呢? –

+0

@Nick!謝謝 - 你釘了它。我的印象是像STL地圖一樣,可以使用[]運算符來動態插入元素。這會讓事情變得完全有意義......奇怪爲什麼STL決定這麼做?這是非常直觀的。我期待當我> 27時,使用[]會簡單地將向量擴展爲當前大小的兩倍並繼續... –

+0

@Nick - 一面注意:讓我感到困惑的是,錯誤消息和我自己錯誤地理解了運算符[]的行爲,導致我錯誤地解釋錯誤,指出我不是以某種方式將正確的參數傳遞給第三方庫。 –

3

不,向量不會自動擴展。您需要expand it yourself

if (n > 27) 
    vec_ints.resize(n, 0); 

+3

我會建議'std :: vector :: reserve(n)'。這確保矢量至少有'n'個元素有足夠的空間。 – Chris

+0

@Chris:恐怕[[reserve]](http://www.cplusplus.com/reference/stl/vector/reserve/)仍然是錯誤的,因爲它確保_capacity_至少是'n',不是_size_。訪問超出其大小的矢量是一個錯誤。 – Vlad

+1

@Chris,那真的不對。調整大小是正確的答案。 'reserve(m)'只保證將來調用'resize(n)',如果n <= m,則不需要移動數據,從而使迭代器失效。 (要擴展@ Vlad的正確點,*容量*總是大於*大小*。在這裏,我們希望* size *至少爲'n') –

1

爲什麼不直接用正確的尺寸開始創建的載體?像這樣:

std::vector<int> vec_ints(n,0); 
std::vector<double> vec_doub(n, 0.);