2016-05-19 10 views
1

私はC++でまだまだ新しいことをお詫びしますので、よろしくお願いいたします。C++配列に最初の要素へのポインタを割り当てる方法は?

私のプロジェクトで変更不可能な制約の一部として、Vectorを配列に変換する必要があります。私の解決策を探しているうちに、私は繰り返しthis oneのような答えを見つけました。

私が理解しているように、この解決策はベクトルの最初の要素へのポインタを与えます。ベクトルがメモリ内で連続していることが保証されているので、配列をそのメモリ位置(またはそれ)。

私の質問は、ですが、C++でどのようにしていますか?答えはそれが簡単なことを示唆しているようですが、私はそれを行う方法を見つけることができません。

std::vector<double> v; 
double* a = &v[0]; 
double myArray[100]; 
&myArray[0] = a; 

は、私はそれから移入」にそのポインタを使うのですか、シーケンスの最初の要素へのポインタを考えると....私はこのような性質のものを試してみましたが、彼らは動作しません。アレイ?さらに、サイズの違いや境界外の問題について心配する必要はありますか?また、逆にこれを行うことはできますか(配列の最初の要素へのポインタを持つベクトルを '取り込む')か?

+0

'double * a = &v[0];'は役に立ちます – Rakete1111

+1

@ Rakete1111それでは配列として使うことができますか?例えばa [3] = 1.5; – jEsp

+1

それは正しいです:) – Rakete1111

答えて

1

あなたは、ベクター例えば

std::vector<double> v; 
double myArray[100]; 

として配列を持っており、配列は次の例の場合と同様に、アレイ内のベクトルの要素をコピーする必要があり、ベクトルの要素を含んであろうとする場合

std::copy(v.begin(), 
      std::next(v.begin(), std::min<std::vector<double>::size_type>(v.size(), 100)), 
      std::begin(myArray)); 

または

std::copy(v.begin(), 
      v.begin() + std::min<std::vector<double>::size_type>(v.size(), 100), 
      myArray); 

あなたは、ベクターが目の要素を持っているであろうとする場合電子アレー、あなたが

v.assign(std::begin(myArray), std::end(myArray)); 

または

v.insert(v.end(), std::begin(myArray), std::end(myArray)); 

それとも、(配列を定義し、充填後)、同時にベクトルを宣言し、それを初期化することができますを書くことができます

std::vector<double> v(std::begin(myArray), std::end(myArray)); 

ことは同じです

5

ベクトルの最初の要素へのポインタを使用して要素をベクトルに挿入することはできません。ベクトルはそのコンテンツを独自に所有しているため、独自のインターフェイスを使用してサイズを変更できるようにする必要があります。そうでなければ、所有する要素の数を追跡できません。

あなたがこれを行うことができます:

std::vector<double> v(N); // N elements initialized to 0.0 
double* a = v.data(); 
do_something(a, N); // tell the function to write N elements 
+0

これは理にかなっています。ありがとうございました。 – jEsp

0

それはあなたが、配列を使用する予定の方法だけでなく、配列やベクトルの寿命に依存します。

あなたは単に配列として、ベクターにアクセスしたい場合、あなたは単にあなたが書かれているようにそれを行うことができます。

double* myArray = &v[0]; 

あるいは、C++ 11以上を使用する:

double* myArray = v.data(); 

これは、配列のようにベクトルmyArrayを使用してアクセスすることができます。効果的に、これはベクトルの内部メモリを別のポインタにエイリアスするだけです。添え字演算子[]はポインタ上で動作するため、myArrayは多かれ少なかれ配列として機能します。

  1. 上記の意志myArrayの寿命が完全にvのそれによって包含される正しく場合にのみ作品:

    しかし、この2つの落とし穴があります。ベクトルが有効範囲外になったり、クリアされたり、にリサイズされた場合、myArrayは無効になります。 vの内部メモリを指しているだけなので、そのメモリを変更するものはすべてmyArrayになります。

  2. ベクトルvにサイズがないため、あなたの例で書いたように、この操作は最初から有効ではありません。住所を取得する前にサイズを指定してください。

アレイにコピーベクトルの内容にしたい場合は、memcpy()を使用することができます。

double* myArray = new double[v.size()]; 
memcpy(myArray, &v[0], v.size() * sizeof(double)); 

これはmyArray現在v内の要素数を割り当て、vに含まれるデータと、そのメモリを移入します。ただし、myArrayの変更はvから独立しています。ベクトルを配列にコピーするだけです。

2番目のオプションを実行するには、いくつかの方法があります。

+0

'std :: fill'は' memcpy'よりも好ましいでしょうから、 'sizeof'で間違いの可能性はありません –

+0

非常に有益な答えです!私の特別な状況では、メソッドはベクトルを返し、配列をデータメンバとして必要とするオブジェクトをインスタンス化するために配列に変換する必要があります。だから、おそらく私はあなたの怪我#1で範囲の問題に遭遇するように思えます。 – jEsp

0

それは、配列リファレンスを作るために可能です:あなたは、ベクター中に挿入した場合

vector<double> v(100); // must size the vector first, or at least add 1 element and call reserve(100) 
double (&myArray)[100] = reinterpret_cast<double(&)[100]>(v[0]); 

その後、あなたはしかしmyArray[0]myArray[1]などを使用することができますし、「移動」にmyArrayは無効になり(そして、それはできませんそれは)。

これは可能ですが、非常に珍しいので、実際のコードでは使用しないでください。

関連する問題