静的リンケージを持つ C++ グローバル多次元配列があります。スタックが割り当てられると想定しています(標準で関連するセクションが見つかりません)。
スタックにはありません。グローバルエリアになります。グローバルおよび静的ストレージ オブジェクトは、ヒープやスタックの一部ではない独自のメモリ領域を取得します。
さらに、スタック (標準では「自動」ストレージと呼んでいます) オブジェクトは、それらが含まれている関数呼び出しの間のみ存続します。グローバルmain()
は呼び出される前に初期化され、終了後に破棄されmain()
ます。
連続して割り当てられていますか?
標準がそれを要求しているとは思えませんが、そうかもしれません。(明確化: 1 次元配列の連続ストレージは保証されていますが、2 次元以上の配列の行間に「ギャップ」がないという保証はありません。) 連続割り当てが必要な場合は、グローバル配列を 1 として宣言します。次元ベクトルを作成し、インライン関数を使用して複数の次元を対応するインデックスに変換します。これは、連続したストレージが保証されている場合にコンパイラが生成するものと同じです。
これらの静的グローバル n-dim 配列をヒープに割り当てられるように変換したいと考えています。コードの変更を最小限に抑えたいと考える最も簡単な方法は何ですか?
グローバル宣言を配列からポインターに変更します。この場合、ストレージをベクトル化することを強くお勧めします。(いいえ、私は について話しているのではなくstd::vector
、1-D ベクトルへの再形成について話しているのです。)
配列を n-dim ポインターに変換することを考えることができます
そのような獣はいません。最後に、ポインターの配列へのポインターです。これは、ベクトルまたはより多くのポインターの配列のいずれかを指し、深さは次元数によって決まります。ND 座標を 1-D インデックスに変換する関数を使用すると、上記の 1-d ベクトルの場合よりもはるかに遅くなります。
main の開始時に malloc'ing し、main を終了する前に free'ing します。
これは、メモリリークを探すためにまたは同様のものをfree
使用していない限り、最後に行う必要がないことを除いて. valgrind
OS は、プロセスの終了時に共有メモリではないすべての割り当てを解放します。
したがって、次のようなものが得られます。
#include <stddef.h>
static const size_t kDimX = 5;
static const size_t kDimY = 20;
static const size_t kDimZ = 4;
inline size_t DimsToVector(size_t x, size_t y, size_t z)
{
return (x * kDimY + y) * kDimZ + z;
}
float* data = 0;
int main()
{
data = new float[kDimX * kDimY * kDimZ];
// Read elements with: data[DimsToVector(x, y, z)]
// Write v with: data[DimsToVector(x, y, z)] = k;
delete[] data; // Optional.
}
operator []
クラスを定義し、いくつかの醜いものを隠すためにオーバーライドする、おそらくBoostのような、より洗練された方法がありますが、これはあなたが始めるための最低限のものです.