私はx軸にn点を持っています。プログラムの開始時に私はnpoints
でxを割り当てています。例えばx = new double[npoints];
newは割り当てを拡大または縮小する方法がないようですか?
シミュレーション中npoints
は異なる場合があります。 npoints
が増えたら、私は割り当てられたメモリを増やしたいと思います。また、npoints
が減少した場合、その縮小されたメモリを削除したいと思います。
私はx軸にn点を持っています。プログラムの開始時に私はnpoints
でxを割り当てています。例えばx = new double[npoints];
newは割り当てを拡大または縮小する方法がないようですか?
シミュレーション中npoints
は異なる場合があります。 npoints
が増えたら、私は割り当てられたメモリを増やしたいと思います。また、npoints
が減少した場合、その縮小されたメモリを削除したいと思います。
::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 malloc
とrealloc
コールを使用する場合は、それらを使用するカスタムvector
クラスを作成することができます。 double
に固有のカスタムクラスを作成しない限り、特別な注意が必要です。メモリが割り当てられた後に追加された任意の要素と、メモリが割り当て解除される前にドロップされた要素のデストラクタでコンストラクタを呼び出す必要があります。
この種のクラスを書くことは複雑です。 C++でのコンテナクラスの期待に応え、他のすべてのものとスムーズに動作させる必要があります。これには、イテレータクラスとその性質のものが含まれます。
小さい値にリサイズしてもメモリは解放されません。メモリを解放することが重要な場合は、vector :: shrink_to_fit()関数を使用する必要があります。 – Jadh4v
@ Jadh4v - それは彼らが作ったように見える興味深いデザインの選択です。私はデザインの選択に同意すると言うことはできませんが、あなたは正しいと思われます。 – Omnifarious
ありがとう。これは本当に役に立ちます。 –