如何在没有内存操作的情况下在C++和STL中定义2D数组?

fee*_*ree 9 c++ arrays stl std stdvector

有几种方法可以在没有内存操作的情况下在C++和STL中定义2D数组,以下代码说明了两种不同的方法:

int main () 
{
    /**************
        1   2   3
        4   5   6
    ***************/
    // Method 1
    const int ROW = 2;
    const int COL = 3;
    int array1[ROW][COL];
    for(int i=0; i<ROW; i++)
        for(int j=0; j<COL; j++)
            array1[i][j] = i*COL+j+1;

    // Method 2
    typedef vector<vector<int> > ARRAY; 
    ARRAY array2;
    vector<int> rowvector;
    for(int i=0; i<ROW; i++)
    {
        rowvector.clear();
        for(int j=0; j<COL; j++)
            rowvector.push_back(i*COL+j+1);
        array2.push_back(rowvector);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:还有其他方法来定义2D数组吗?哪一个最有效?谢谢!

Pio*_*ycz 16

在C++ 11中使用std::array:

  std::array<std::array<int,3>,2> a {{
    {{1,2,3}},
    {{4,5,6}}
 }};
Run Code Online (Sandbox Code Playgroud)

一些用法:

  a[0][2] = 13;
Run Code Online (Sandbox Code Playgroud)


Ron*_*nis 7

定义数组的一种非常有效的方法是使用newdelete运算符进行动态分配.这是一个例子:

int **arr=new int*[ROW];
for( int i=0; i<ROW; ++i ) {
  arr[i] = new int[COL];
  for( int j=0; j<COL; ++j ) {
    arr[i][j] = some_val;
  }
}
Run Code Online (Sandbox Code Playgroud)

这种方法的最大优点是,当您不再需要阵列使用的内存时,您可以轻松删除它.以下是删除2D数组的示例:

for( int i=0; i<ROW; ++i ) {
  delete[] arr[i];
}
delete[] arr;   
Run Code Online (Sandbox Code Playgroud)


jap*_*iss 6

这里有很多权衡取舍.

如果声明一个C风格的2D数组int array[height][width],那么你真的会获得一个连续的内存块.编译器将索引转换为其1D地址

array[row][col] == *(array + row * width + col)
Run Code Online (Sandbox Code Playgroud)
  • 优点:缓存一致性.所有的记忆都在同一个地方.
  • 缺点:每个索引都需要乘法.间接可能更快.

如果您使用vectorvectors,则每行单独分配.外部vector存储指向内部的指针vectors.索引成为间接,然后添加:

array[row][col] == *(*(array + row) + col)
Run Code Online (Sandbox Code Playgroud)
  • 优点:间接可能比乘法更快.
  • 缺点:不缓存一致,因为每行都是单独分配的(除非实现优化vector<vector>).

如果性能真的很重要,那么您需要测试两者并找出哪些数据更快.


Dav*_*eas 6

一种常见的模式是将2D数组封装在提供适当接口的类中.在这种情况下,您可以使用其他内部表示,例如单个rows*cols元素向量.界面(通常operator()(int,int)将坐标从调用者映射到线性向量中的位置.

优点是它具有动态分配,但是单个分配(不同于std::vector<std::vector<int>>每个向量必须获取其自身存储器的位置),并且在单个块中提供数据的位置.


Hei*_*bug 4

还有其他方法来定义二维数组吗?

如果没有显式操作内存(malloc/free),则不会。如果您使用静态分配数组(第一个示例),您将在编译时分配空间,因此您无法在运行时添加更多行或列。

第二个示例使用std::vector它向您隐藏动态内存分配。这样您最终可以在运行时添加更多行或列。

如果不需要动态修改数组维度,那么第一个解决方案是更简单、更快的解决方案(即使我认为 std::vector 实现足够快,可以与静态数组相媲美,更优雅,更面向对象) )。

如果需要在运行时修改数组维度,请使用 std::vector,因为它可以让您免于直接处理 malloc 和 free。