计算巨大尺寸的3D阵列中的元素总和

时间:2017-05-06 20:15:49

标签: c++ arrays 3d

我创建了一个大小为[100] [100] [100]的3D数组。在开始时,由于这个巨大的数组,我在编译代码时遇到了一些错误。经过一番挖掘后,我在C ++程序中将此数组声明为全局和静态。现在我的要求是我必须计算该数组的所有元素的总和。在这样做时,我尝试循环遍历数组,并在一段时间后在运行时得到段片段错误。

任何人都可以建议我应该怎么做吗?有没有更好的方法来计算总和?

由于

我的代码在这里给出

for(int m=0;m<dimension;m++){
        for(int j=0;j<dimension;j++){
            for(int k=0;k<dimension;k++){
                a[m][j][k]=0;
        }
    }
}

这就是我计算总和的方法

int sum=0;
for(int i=x1;i<=x2;i++){
    for(int j=y1;j<=y2;j++){
        for(int k=z1;k<=z2;k++){
            sum=sum+a[i][j][k];
        }
    }
}

其中x1,x2,y1,y2,z1,z2作为用户输入。

我在第一部分没有出现任何错误,但在代码的第二部分出现了分段错误错误。

3 个答案:

答案 0 :(得分:2)

在第二个代码片段中,您使用用户输入作为数组维度而不进行边界检查。始终,始终 始终 边界 - 检查您的阵列访问。

在这种情况下,快速而肮脏的方式是:

assert(x1 >= 0); // Unless x1 is unsigned.
assert(y1 >= 0); // Unless y1 is unsigned.
assert(z1 >= 0); // Unless z1 is unsigned.
assert(x2 < dimension);
assert(y2 < dimension);
assert(z2 < dimension);

同时检查a的初始化。如果它是动态分配的,请检查返回码。

或者用代码替换以从错误中恢复。运行时成本可以忽略不计,因为您在循环外执行此操作。此外,如果您的维度声明为constexpr size_t dimension = 100;并且a声明为static int a[dimension][dimension][dimension];(或对具有已知边界的数组的引用),则可以使用,

memset( &a, 0, sizeof(a) );

否则,对于动态数组,您可以使用:

memset( &a, 0, sizeof(int)*dimension*dimension*dimension );

但是,当程序启动时,静态分配的全局数组将初始化为零。

如果您使用std::array,它将为您执行边界检查,而不会产生额外的内存开销。

答案 1 :(得分:0)

使用3D阵列通常不是一个好主意 您可以尝试仅使用一个for循环求和,如下所示,以避免嵌套:

int D = dimension;
int sum = 0;
for (int i = 0; i < D*D*D; ++i)
        sum += A[i / (D * D)][(i / D) % D][i % D];

答案 2 :(得分:0)

虽然可能不是你我们希望的答案。我会切换到boost multi_array。通过声明1000或100甚至100的标准阵列,我可以重现您的问题。使用boost多阵列我没有那个问题。见下面的代码:

//Boost:ublas
#include <boost/numeric/ublas/matrix.hpp>
#include "boost/multi_array.hpp"
#include <boost/date_time/posix_time/posix_time.hpp>
#include <cassert>

//Using declarations
using namespace boost::numeric::ublas;

int main() {
    cout << "Start Time: " << time(0) << endl;
    time_t t0 = time(0);

    //Example taken and adjusted from: http://www.boost.org/doc/libs/1_56_0/libs/multi_array/doc/user.html
// Create a 3D array that is 3 x 4 x 2
    typedef boost::multi_array<int, 3> array_type;
    typedef array_type::index index;
    int const size =1000;
    array_type A(boost::extents[size][size][size]);

    // Assign values to the elements
    for (index i = 0; i != size; ++i)
        for (index j = 0; j != size; ++j)
            for (index k = 0; k != size; ++k)
                A[i][j][k] = 1;

    // Verify values
    int sum = 0;
    for (index i = 0; i != size; ++i)
        for (index j = 0; j != size; ++j)
            for (index k = 0; k != size; ++k)
                sum += A[i][j][k];

    std::cout << "Sum:  " << sum << endl;

    cout << "End Time: " << time(0) << endl;
    time_t t1 = time(0);

return 0;
}

希望这可以解决您的问题。

正如我在评论中提到的那样,我认为你的问题是你声称的内存比你的操作系统所允许的更多而没有特别的考虑,但我不能轻易确认。

万一你不知道提升,Boost库是一个很棒的工具箱,具有很多功能,并且多年来为C ++标准做出了很多贡献。所以我建议使用它。