2017-01-02 7 views
0

私はx軸にn点を持っています。プログラムの開始時に私はnpointsでxを割り当てています。例えばx = new double[npoints];newは割り当てを拡大または縮小する方法がないようですか?

シミュレーション中npointsは異なる場合があります。 npointsが増えたら、私は割り当てられたメモリを増やしたいと思います。また、npointsが減少した場合、その縮小されたメモリを削除したいと思います。

答えて

10

::std::vectorを使用してください。

#include <vector> 

void foo() 
{ 
    ::std::vector<double> x; 
    x.resize(5); 
    x[4] = 2.0; 
    x.resize(2); 
    // etc... 
} 

あなたが言及しているユースケースは、正確には::std::vectorとなっています。

小さいサイズのベクトルのサイズを変更すると、通常はメモリの割り当てが解除されません。これは多くの理由で、shrink_to_fitでこのStackOverflowの質問は、なぜ説明:あなたは本当に余分なポイントの割り当てが解除されなければならないという実装にヒントにしたい場合は、Is shrink_to_fit the proper way of reducing the capacity a `std::vector` to its size?

しかし、次の操作を行います。

#include <vector> 

void foo() 
{ 
    ::std::vector<double> x; 
    x.resize(5); 
    x.shrink_to_fit(); // It didn't get smaller here, but I'm guessing you may 
    x[4] = 2.0;  // not know that when you resize the vector in your own code. 
    x.resize(2); 
    x.shrink_to_fit(); 
    // etc... 
} 

ベクトルはまだ実際には割り当てを縮小しないかもしれません。それが本当に問題であれば、実装に取り​​組むのは問題です。

それは問題であり、あなたは絶対に割り当てを縮小しており、実装が固定されるように得ることができない、あなたがこれを行うことができれば:

#include <iterator> 
#include <algorithm> 
#include <utility> 
#include <vector> 

template <class T> 
void shrinkwrap_vector(::std::vector<T> &x) 
{ 
    using namespace ::std; 
    typedef vector<T> vec_t; 

    const auto old_cap = x.capacity(); 
    x.shrink_to_fit(); // Try shrink_to_fit first to see if it works. 
    if ((x.capacity() == old_cap) && (old_cap > x.size())) { 
     vec_t t; 
     t.reserve(x.size()); 
     move(x.begin(), x.end(), back_inserter(t)); 
     swap(x, t); 
    } 
} 

そしてちょうど

を呼び出します
shrinkwrap_vector(x); 

のコードでx.shrink_to_fit()の代わりに。それは、あなたの実装が得られる大きさに近い新しいベクトルにあなたのベクトルをコピーするだけです。

デストラクタが些細なデストラクタを持つものを格納している場合は、resizeを実行すると、そのデストラクタが削除された要素ごとに呼び出されます。 shrink_to_fit全体は、メモリの割り当てに関するものであり、構築や破壊に関するものではありません。

最後に、実際にC mallocreallocコールを使用する場合は、それらを使用するカスタムvectorクラスを作成することができます。 doubleに固有のカスタムクラスを作成しない限り、特別な注意が必要です。メモリが割り当てられた後に追加された任意の要素と、メモリが割り当て解除される前にドロップされた要素のデストラクタでコンストラクタを呼び出す必要があります。

この種のクラスを書くことは複雑です。 C++でのコンテナクラスの期待に応え、他のすべてのものとスムーズに動作させる必要があります。これには、イテレータクラスとその性質のものが含まれます。

+3

小さい値にリサイズしてもメモリは解放されません。メモリを解放することが重要な場合は、vector :: shrink_to_fit()関数を使用する必要があります。 – Jadh4v

+0

@ Jadh4v - それは彼らが作ったように見える興味深いデザインの選択です。私はデザインの選択に同意すると言うことはできませんが、あなたは正しいと思われます。 – Omnifarious

+0

ありがとう。これは本当に役に立ちます。 –

関連する問題