2013-04-15 15 views
5

へのポインタのベクトルを作成するには:どのように私は、ベクターへのポインタを持つベクトル

vector<double> mv; 
mv.push_back(233); 
mv.push_back(234); 
mv.push_back(654); 
vector<double>* new_mv_pt = new vector<double> (3); 
new_mv_pt = &mv;  

cout << (*new_mv_pt)[1] << endl;  

がどのように私はベクトルにこのポインタを格納する別のベクトルを作ることができますか? 私はこれを試していました...

vector<double*> vop = new vector<double> (3); 

vop.push_back(*new_mv_pt); 

cout << (*vop)[1] << endl; 

しかし、うまくいきませんでした。私は

+2

まず、回答を得てください。第二に、これは恐ろしい考えであることに気付く。なぜなら、最初に使用するポイントの半分以上の、あなたのためにメモリを管理するベクターの能力を排除しているからです。 –

+0

私は、なぜ彼が最初にベクターへのポインタを持っているのか理解しようとしています。これは、特に同じ関数/クラスにある場合、このようにするのは概念的に意味がありません。 –

答えて

3

はい?:でも可能しようとしていますが、あなたはこれを行う必要がありますされているもの:

vector<vector<double>*> vop; 

あなたは、ベクトルポインタのリストを探していますので。

あなたがここに持っているもの:

vector<double *> vop 

はちょうどdoubleポインタのベクトルです。

また、あなたはこのちょうどたいと思うでしょう:あなたがここでメモリリークを持って

vop.push_back(new_mv_pt); // <- No asterisk (you don't want to de-reference it) 
+0

メモリ内のリークを回避するために両方のポインタを削除する方法はありますか? new_mv_ptを削除しようとしましたが、実行時に何らかのアサーションエラーが発生します。どうしたの? –

+0

両方のポインタをどういう意味ですか?あなたは 'new_mv_pt'とベクトルの1つを意味しますか? –

+0

よく、ポインタのベクトルに入れないでnew_mv_ptを削除しようとすると、動作しなくなり、実行時にある種のアサーションエラーが発生します。最後には、すべてを安全に削除する方法を知りたいと思います。 –

2

を:

vector<double>* new_mv_pt = new vector<double> (3); 
new_mv_pt = &mv; 

あなたは、ヒープ上vector<double>を作成することがnew_mv_ptのアドレスです保存し、その後していますは、アドレスがmvのアドレスを上書きします。 vector<double>は依然としてヒープ上に存在しますが、アドレスは永久に失われているため、deleteにアクセスすることはできません。

このコード:vopdouble*秒のベクトルであり、あなたがそれにvector<double>を挿入しようとしているため

vector<double*> vop = new vector<double> (3); 
vop.push_back(*new_mv_pt); 
cout << (*vop)[1] << endl; 

は動作しません。正しいアプローチについては、Ben's answerを参照してください。

7

おれ、遅く!

あなたの記憶でかなり狂ったことをしているので、最初から始めましょう。

あなたは3つの要素を持つ単一のベクトルを持っています。ポインタを使ってそのベクトルを参照したいとします。どのように見えるかを見てみましょう:

vector<double> mv; 
mv.push_back(233); 
mv.push_back(234); 
mv.push_back(654); 
// No no no no! You don't have to `new` a pointer that 
// you're going to assign to something else! 
// This is called a memory leak, and it means you've just wasted (!!!) 
// C++ memory! Don't do it 
// vector<double>* new_mv_pt = new vector<double> (3); 
// Instead, do this: 
vector<double>* ptr_to_mv = &mv; // No leak, immediately points to a vector<double> mv; 

最初のビットが処理されます。さて、少し深めてみましょう。ベクトルへの参照のベクトルを保存します。申し訳ありません。それについてはいくつかの方法があります。さんがmvや他のものの例に戻りましょう:

vector<double> mv; 
mv.push_back(233); 
mv.push_back(234); 
mv.push_back(654); 
vector<double>* ptr_to_mv = &mv; 
// So far so good. Now, based on your question, you want 
// to have a list of these to point to. So: 
vector<vector<double>*> vop; 
vop.push_back(ptr_to_mv); // All clean. 

あなたのコード内のこの時点で、あなたは*または使用して、それを間接参照し、その後、vector<double>*に到達するために.at()またはoperator[]vopにアクセスする必要が->が直接その上で動作するように:このすべてがmvをご参照しているので

std::vector<double>* ptr_to_vector = vop[0]; // Got my pointer 
std::cout << ptr_to_vector->at(0) << std::endl; // Prints '233' 

をこれが233を印刷します。別の答えのコメントでは、これらのポインタを削除するとアサーションが得られると言っています。 これは、あなたが物事を2回削除しているので、起こるはずです!

あなたは長い間前に宣言したmvを覚えていますか?まあ、あなたはそれを動的なベクトルにしていませんでした。あなたはnewではありませんでした。それはポインタではありません。したがって、関数が終了すると自動的に削除され、デストラクタが呼び出され、スタック上にが死ぬ。ptr_to_vectorまたはptr_to_mvを見ると、それらはすべてmvを参照しており、それ自体が消去されます。

あなたが削除を呼び出すと、あなたはmvの削除を呼び出そうとしています(あなたが指していることです)、あなたは二重削除しています!

mvへのポインタがある場合、それを削除しないでください。これはスタックベースの変数です。それは自分自身をきれいにするでしょう。

まだまだ続きますか?偉大な、のは、もう少しそこに取得してみましょう:あなたは、ベクトルをアップnewする必要が理由があるのなら、私は前にあなたに言ったとして今

、あなたは、(旧ポインタでそれを上書き割り当てませんあなたは記憶を残すでしょう)。それだけだから、我々は、両方のないよう、別の1が、削除を呼び出すことによってクリーンアップする必要がvop、内側と2つのポインタを持っている:

// Our vector of double vector pointers 
vector<vector<double>*> vop; 

vector<double> mv; 
mv.push_back(233); 
mv.push_back(234); 
mv.push_back(654); 

// References a stack variable: don't delete 
vector<double>* ptr_to_mv = &mv; 
vop.push_back(ptr_to_mv); 

// Makes a fresh copy of mv. You must delete this 
// manually 
vector<double>* fresh_ptr = new vector<double>(mv); 
(*fresh_ptr)[0] = 1337; 
// changes only data in fresh_ptr, not `mv` 
vop.push_back(fresh_ptr); 

/* Blah blah blah, work */ 
// Functions about to exit, gotta clean up! 
delete fresh_ptr; 
//delete ptr_to_mv; // NO. 
//delete vop[0]; // NO! 
//delete vop[1]; // ... Already deleted from fresh_ptr 
// ... This is going to get tedious if we don't have a fresh_ptr 
// for every vector we need! 
上記

問題を示しています。あなたは完全に新鮮な新しいポインタを作ります自動的にクリーニングするmvへの参照!ベクトルをループしてすべてを削除すると、その厄介なアサーションが発生します。私たちはそれをどのように扱い、まだ必要なクリーンアップを得るのでしょうか?

ダーティークイックソリューション1はちょうどdelete vop[1]/fresh_ptrになります。より良い解決策は、newのリソースを使うときはいつでも、std::unique_ptrと呼ばれるこの素敵なものにまとめます。コードは次のようになります:

そしてそこにコメントアウトされたコードをすべて削除してください。突然、あなたのものは笛のようにきれいです!もちろん

、今、あなたのために私が持っている最後の質問です: あなたはそれをどのような地獄をやっているのは、ベクトルのポインタの参照にポインタへのすべてのこれらのポインタを必要としますか?

+0

これは非常に役に立ちました。あなたは私をたくさん動かす。どうもありがとうございました。 –

+0

これは非常に簡単な質問に対する信じられないほど詳細な答えです。あなたはプロです! +1 –

関連する問題