2011-10-21 14 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 

だから、少なくとも明示的なサイズ変更が使用されていないこのような状況での使用のために、意図/期待通りに動作しているようです。

答えて

3

std::vector<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

@ニック!ありがとうございました。私はSTLマップのように、[]演算子を使って要素を動的に挿入することができたという印象を受けました。 STLがこれをすることを決めたのはなぜだろうか?これは非常に直感的です。私は> 27を使用すると、[]を使用するとベクトルを現在のサイズの2倍に拡大して続行することを期待していました。 –

+0

@Nick - 片側の注釈:エラーメッセージと私自身の間違った考え方operator []は動作し、エラーを間違って解釈し、私が何らかの理由で第三者のlibに正しい引数を渡していないことを示しました。 –

3

いいえ、ベクターは自動的には展開されません。あなたはexpand it yourselfする必要があります:あなたはstd::vector<T>::push_back(T &)std::vector<T>::insert(iterator, T &)(おかげでK-BALLO)または明示的にはstd::vector<T>::resize(size_t)を呼び出して使用して要素を追加する場合は

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

など

+3

私は 'std :: vector :: reserve(n)'を提案します。これは、ベクトルに少なくとも "n"要素のための十分な余地があることを保証します。 – Chris

+0

@Chris:_capacity_が少なくとも「n」であることを保証するので、[reserve](http://www.cplusplus.com/reference/stl/vector/reserve/)はまだ間違っています_size_ではありません。サイズを超えてベクターにアクセスするのはエラーです。 – Vlad

+1

@Chris、それは本当に正しいわけではありません。 'resize'は正解です。 'reserve(m)'は、 'resize(n)'への将来の呼び出しが、n <= mの場合、データを移動する必要がなくイテレータを無効にすることを保証するだけです。 (@ Vladの正しい点を拡張するために、* capacity *は常に* size *より大きい。ここでは、* size *を少なくとも 'n 'にする) –

1

ような何かをしたいですか?同様に:

std::vector<int> vec_ints(n,0); 
std::vector<double> vec_doub(n, 0.); 
関連する問題