1

C++ で 4 次元配列の動的メモリ割り当てを行う最も簡単で、もちろん最も正確な方法は何かと考えていました。私がすでに知っていることは次のとおりです。

double**** A;
A = new double***[s1];
for (i = 0; i < s1; i++) {
    A[i] = new double**[s2];
    for (j = 0; j < s2; j++) {
        A[i][j] = new double*[s3]; 
        for (k = 0; k < s3; k++) {
            A[i][j][k] = new double[s4];
        }
    }
}

次元x x xAの 4 次元配列として宣言します。s1s2s3s4

ただし、上記は安全ではありません。newの 1 つがメモリの割り当てに失敗した場合、これに気付かずにループが継続するという意味で。

try上記を少し安全にするために、 /catchブロックで囲むことができます。これにより、bad_allocがスローされた後にコードが続行されnewず、コードが存在しないメモリ要素にアクセスしようとせず、プログラムがこれで停止する可能性があります。点。

これは問題ありませんが、既に割り当てられているメモリはプログラムが終了する前に解放されません。ij、およびの値を使用して、理論的には、kどのメモリ要素が既に割り当てられているかを正確に判断して解放できる必要があります。しかし、私はそれを行う簡単な方法を考えることはできません。

2 次元の場合、次のようにします。

double** A;
try {    
    A = new double*[s1];
} catch(bad_alloc& ba) {
    delete[] A;
    throw ba; // or end the program
}
try {
    for (i = 0; i < s1; i++)
        A[i] = new double[s2];
} catch(bad_alloc& ba) {
    while(--i) {
        delete[] A[i];
    }
    delete[] A;
    throw ba; // or end the prog.
}

上記は、より高次元の配列に一般化できますが、非常に見苦しいと思います! だから、それを行うためのより良い方法があるのだろうか?


私の場合A[i][j][k]、ゼロ以外の要素がほとんどないベクトルであることにも言及する必要があると思います。したがって、s3ゼロ以外の要素の数と同じ大きさにするだけです(そして、インデックスのマッピングを処理します...後で)。s3ただし、 によって異なりますj。そのため、従来のメモリ割り当てを使用する方が、次のような高レベル API よりも簡単です。vector

4

2 に答える 2

3
std::vector<std::vector<std::vector<std::vector<double>>>> A;

これにより、例外の安全性を管理する心配をせずに 4D 動的配列を取得できます (少なくともメモリ割り当ての場合)。

静的配列が必要な場合:

std::array<std::array<std::array<std::array<double, N>, N>, N>, N> B;

補足: そこまで入れ子にしている場合は、おそらくリファクタリングによって多くのことを得ることができます。

そのため、従来のメモリ割り当てを使用する方が、ベクターなどの高レベル API よりも簡単です。

それは欠陥のある主張です。非スパース 4D 配列があります。Boost Multiarrayを使用するよりも「従来のメモリ割り当て」を使用std::vectorすることで、ほとんど何も得られません。std::array適切なメモリ管理と例外の安全性のために実行する必要がある同じ手順はすべて、これらのクラスで既に行われています (十分にテストされています) が、カスタム実装はそうではありません。

于 2013-10-07T14:13:18.563 に答える
2

Nd 配列であるメモリのブロックが本当に必要な場合は、次のことを試すことができます。

int* raw_mem = new int [S1 * S2 * S3];
int (*arr)[S2][S3] = (int (*)[S2][S3]) raw_mem;

これは、メモリのブロックを真の 3 次元配列のようにアドレス指定するだけです。

さて、これは最悪の方法です。他の回答で提案されている高レベルの API を使用する必要があります。しかし、メモリのブロックを C マルチアレイとして扱うことは可能です。

于 2013-10-07T14:14:06.450 に答える