这个2D阵列初始化是个坏主意吗?

时间:2010-05-16 03:16:18

标签: c++ multidimensional-array memory-management

我有一些东西我需要一个2D数组,但为了更好的缓存性能,我宁愿让它实际上是一个普通的数组。这是我的想法,但我不知道这是一个可怕的想法:

const int XWIDTH = 10, YWIDTH = 10;
int main(){
    int * tempInts = new int[XWIDTH * YWIDTH];
    int ** ints = new int*[XWIDTH];
    for(int i=0; i<XWIDTH; i++){
        ints[i] = &tempInts[i*YWIDTH];
    }
    // do things with ints
    delete[] ints[0];
    delete[] ints;
    return 0;
}

所以我的想法是,不是new一堆数组(并将它们放在内存中的不同位置),而是指向我一次制作的数组。

delete[] (int*) ints;的原因是因为我实际上是在一个类中执行此操作,它会保存[微不足道的]内存而不保存原始指针。

只是想知道是否有任何理由这是一个可怕的想法。或者,如果有一个更容易/更好的方式。目标是能够以ints[x][y]而不是ints[x*YWIDTH+y]访问数组。

编辑:一个简单的基准测试表明,如果没有优化器,我的方式会更快,但由于某种原因,gcc可能会以简单的方式更好地优化。

http://pastebin.com/YDRuLuXv

如果用gcc -O0编译,最好应该是堆栈,然后是我的,然后是正常的。如果你在X_MAX设置为较大值并且Y_MAX设置为较小值的情况下进行编译,并使用gcc -O3,则我的和堆栈应该非常快,但正常情况不会。如果你使X_MAX变小并且Y_MAX很大,那么正常的方法应该会胜出(因为某些原因,甚至超过了堆栈方法)。

3 个答案:

答案 0 :(得分:2)

这种方法的问题在于它容易出错。我会告诉你在一个类中包装和访问你的2D数组中的各个元素。

class Array2D
{
private:
    /* Pointer necessary for the choosen implementation */
public:
    Array2D(unsigned int dim1, unsigned int dim2);
    ~Array2D() /* Needed, since you will be allocation memory for this class */
    double operator()(unsigned int x, unsigned int y);
}

在这种情况下,如果您觉得需要更改分配,则只能更改方法实现,保持接口完好无损。其余的代码实际上只使用operator()和构造函数。它还可以帮助您防止内存泄漏。

答案 1 :(得分:1)

我认为你在过早的阶段不必要地进行微观优化。而不是担心这一点,只需尽可能最简单的方式使程序正常工作。

如果您需要2D数组,只需声明并使用它即可。错误和维护的减少将远远超过任何可能根本不存在的性能提升。

答案 2 :(得分:0)

我找到了更好的方法。 Boost有一个多维数组库:boost::multi_array

this question获得了这个想法。