繁体   English   中英

C ++ 2D动态数组

[英]C++ 2D Dynamic Array

我试图动态地将2d数组分配给构造函数初始化中的指针。

FooBar::FooBar()
    : _array( new int[10][10] )
{ }
int **_array;

但是这不起作用。 我知道多维数组的分配有点不同。 是否有人能够通过解释详细说明这一点?

提前致谢。

这里的一些答案说二维数组是指向其他数组的指针数组。 那不是真的(存储指针的地方,如果你分配的只是数组的数据!?)。 相反,二维数组是其他数组的数组。 因此,您必须更改成员的类型:

FooBar::FooBar()
    : _array( new int[10][10] )
{ }
int (*_array)[10];

这是因为new[]返回一个指向所创建数组的第一个元素的指针。 此元素是10个整数的数组,因此成员类型更改。 如果语法吓跑了你,用temlate简化它(这个模板相当于boost::identity )。

template<typename T> struct identity { typedef T type; };

FooBar::FooBar()
    : _array( new int[10][10] )
{ }
identity<int[10]>::type *_array;

这有效地像就地typedef一样工作。 当然,就像使用new[] ,它需要在析构函数中放置一个正确的delete[] ,并在对象被销毁时调用。

由于new[]分配了一个在编译时具有已知类型的元素数组,因此您只能将第一个(最外部)维度设置为运行时值 - 所有其他维度必须在编译时具有已知值。 如果这不是你想要的,你将不得不分配一个指针数组,就像其他一些答案所说的那样。

但请注意,为避免进一步混淆,那些不是多维数组。 它们是指针的一维数组,恰好指向其他一维数组。

C中的二维数组是指向其他数组的指针数组。

假设我们有3x3数组a (typed int** ):

a[0] (a[0] is of type int*) = [0][1][2]
a[1] (a[1] is of type int*) = [0][1][2]
a[2] (a[2] is of type int*) = [0][1][2]

这意味着需要两个分配传递,一个用于指针数组(int **),其余用于每个数组的元素。

首先,分配一个指针数组:

int** a = new int*[10];

第二遍中,对于每个a的元件,分配一个新的数组:

for(int i=0; i<10; ++i)
    a[i] = new int[10];

这将为您提供C ++中的“二维”数组。

正如您所看到的,在更高的维度上这可能非常麻烦,因此另一个技巧是分配10 * 10个元素并将数组用作2D(又称“投影”):

const int ARRAY_WIDTH = 10;
const int ARRAY_HEIGHT = 10;
int* a = new int[ARRAY_WIDTH * ARRAY_HEIGHT];

    // To access a[5][2] you would use: 
a[5 + (2 * ARRAY_WIDTH)] = 0;
int **array  = new int *[10];

for(int i= 0; i< 10;i++)
{
    array[i] = new int[10];
}

如果您使用的是新的,则需要分别分配第二个维度的每个部分。

int **Array;
Array = new int*[10];
for (int i = 0; i < 10; i++) {
    Array[i] = new int[10];
}

如果您不太关心性能,可以使用以下内容:

//vec2d.h
#include<vector>

template<class T>
void init2DVect(std::vector< std::vector<T> >& _T, size_t sx, size_t sy)
{
  _T.resize( sx );
  for(size_t i =0; i < sx; ++i)
  {
    std::vector<T> ins_v(sy);
    _T[i] = ins_v;
  }
}

用例示例:

//file: vec2d_test.cpp
#include "vec2D.h"

#include<cassert>

int main()
{
  std::vector< std::vector<int> > vi;
  size_t sx = 5;
  size_t sy = 7;
  init2DVect(vi, sx, sy);

  for(size_t i = 0; i < sx; ++i)
  {
    for(size_t j = 0; j < sy; ++j)
    {
      vi.at(i).at(j) = i*j;
    }
  }

  for(size_t i = 0; i < sx; ++i)
  {
    for(size_t j = 0; j < sy; ++j)
    {
      assert( vi.at(i).at(j) == i*j );
      assert( vi[i][j] == i*j );
    }
  }   

  return 0;
}

这样做的好处是你不必担心内存,你可以使用vector :: at()函数,以便在你超出范围时抛出一个异常......对于C ++的家庭作业很有用,但是一个向量std :: vector必然不是最快的方法。

Othewise TNT库可以解决这个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM