2016-06-20 4 views
0

here見られるように、私はdoubleの配列にdoubleのベクトルを変換しています:ベクトルを配列に変換します。メモリの割り当てを解除するには?

を違いは、私は、関数のパラメータとしてポインタaを返すようにしたいということ、である:

void getArray(double* a) 
{ 
    std::vector<double> v; 
    a = &v[0]; 
} 

だから私の質問ですaのメモリはいつ解放されますか?または私はdelete[] aに電話しなければならないのですか?私はnewでメモリを割り当てなかったので、奇妙に思えます。私は上記の答えにコメントを読んだが、それでも私には分かりません。

+3

'a'はゴミを指します。一度' v'がスコープ外であれば、何も削除されません。 – user463035818

+0

あなたがそこに見るように、関数呼び出しは関与していません。 –

+0

@DieterLücking何を意味するのですか?デストラクタは関数ではありませんか? – Basilevs

答えて

6

ベクトルvが破棄されると、aが指すメモリが解放されます。この場合、それは関数getArrayの最後にあります。

+0

@Basilevs OPが何をしようとしているかによって異なります。あなたがメモリを破壊したければ?誰がこれを管理する必要がありますか? – Kupiakos

+2

@Basilevsメモリ管理の良いアプローチは、ベクトルをベクトルとして保持し、手動で管理する代わりにメモリを管理することです。それは本当に最終目標にかかっています。実行すべきではないものの使用例は、そうすることが正しいことを示唆しているかもしれません。現代のC++プログラマは生ポインタを避けるべきです。 – Kupiakos

1

はこれをしないでください。いずれの場合で

void getArray(double* a) 
{ 
    std::vector<double> v; 
    a = &v[0]; 
} // The vector is destroyed here, and the memory 
    // is deallocated. 

は、あなたがあなたの関数の外 aポインタを変更していない、あなたは所望の効果を得ることはありませんので。

代わりにvectorを返して、直接使用してください。または、一般的に、コード全体でベクトルを使用します。配列へのポインタを期待する関数にに渡す必要がある場合は、そこに&v[0]を渡すことができます。そのような関数は、通常、サイズも期待しています。これには、v.size()を渡します。これは、その関数が所有権を取得していないか、メモリの割り当てを解除していない限り、安全に行うことができます。

std::vector<double> v;と宣言されたベクトルにはサイズがないため、v[0]のように最初の要素にアクセスしようとすると、未定義の動作になります。少なくとも、ある程度のメモリが確保されるように、ベクトルにサイズを渡す必要があります(コンストラクタにサイズを渡す)。最初の要素のアドレスを取得しようとするときを含めて、ベクトルにインデックスを付ける前に必ずベクトルに割り当てられたメモリがあることを確認する必要があります。あなたはおそらく何をしたいのか

は次のとおりです。

std::vector<double> getArray() { 
    std::vector<double> v = /* some sane initialisation */; 
    return v; 
} 

// some time later, assuming a function: 
// void do_something(double* a, size_t n); 
// ... 

std::vector<double> v = getArray(); 
if (v.size()) { 
    do_something(&v[0], v.size()); 
} else { 
    // fail gracefully 
} 
1

vがローカルであるため、この実装は未定義の動作を呼び出します:

void getArray(double* a) 
{ 
    std::vector<double> v; 
    a = &v[0]; // would be a UB for returning the pointer to internals of a local variable. 
} 

しかし、呼び出し側は、この任意の効果を見ることはありません、ので、 aへの変更はgetArray機能にローカルに留まる。

ベクトルから配列を作成する場合は、新しい配列を割り当て、std::copyを使用して内容をコピーし、配列を呼び出し元に返します。

vector<double> data; 
data.push_back(...); 
... // populate the vector 
double *tmp = getArray(data); 
... // Use the array 
delete[] tmp; // Avoid memory leaks 
+1

あなたが言ったように、aの変更は関数のローカルなので、私はそこにubがあるとは思わない。 – user463035818

+1

@tobiサイズで構築されていないベクトルの 'v [0]'にアクセスするときにUBがあります。 – Andrew

+0

@Andrewああ、私は彼が無効なポインタを逆参照することを指していると思っていた(実際には "vはローカルなので誤解を招く") – user463035818

1

のメモリの割り当てが解除されますない場合:?彼らはcopyL

で行われた後、発信者が次のように呼び出し側がそれを使用する必要があり
double *getArray(const vector<double>& v) { 
    double *res = new double[v.size()]; 
    std::copy(v.begin(), v.end(), res); 
    return res; 
} 

結果にdelete[]を呼び出していることを確認しますか

aポインタ自体はローカル変数であり、それは、その範囲の端部に割当て解除されます。

aは、ベクトルvによって割り当てられたメモリを指します。指し示されたメモリは、デストラクタのvで解放されます(オブジェクトはベクトルに追加または削除されるとメモリが解放されることもあります)。 vはローカル変数であるため、スコープの終わりに破棄されます。

それとも、私はdelete []を呼び出す必要はありません自分で、

いいえ、メモリは、だけでなく、ためにベクトルオブジェクトによって所有されているためので、奇妙なよう

私は新しいメモリを割り当てませんでした。

正確に。 new[]に電話していないので、delete[]に電話しないでください。


v[0]は、ベクターが空であるため、未定義の動作があります。

関連する問題