1

我想知道在 C++ 中为 4-D 数组分配动态内存的最简单当然也是最准确的方法是什么。我已经知道的是:

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];
        }
    }
}

声明A为维度为s1x s2x s3x的 4-D 数组s4

但是,上述方法并不安全。从某种意义上说,如果其中一个news 未能分配内存,则循环会继续,而不会注意到这一点。

为了使上面的内容更安全一点,我们可以将它包含在try/块中,这样代码在 a被抛出catch后不会继续,并且代码不会尝试访问一些不存在的内存元素,并且程序可以在此停止观点。bad_allocnew

这是可以的,只是已经分配的内存在程序完成之前不会被释放。从理论上讲i,我们必须能够准确地说出哪些内存元素已经分配并释放它们jk但我想不出一个直接的方法来做到这一点。

对于二维情况,我会做这样的事情:

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(如 vector)更容易的原因

这是一个有缺陷的断言。您有一个非稀疏 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-d 数组一样被寻址。

现在,这是最糟糕的方法。您应该使用其他答案中建议的一些更高级别的 API。但是可以将一块内存视为 C 多数组。

于 2013-10-07T14:14:06.450 回答