使用C++new[]为2D阵列分配内存



当我从用户那里读取一些值,并且我需要创建一个特定大小的数组时,我会这样做:

#include <iostream>
using namespace std;    
unsigned* numbers;
int main()
{
int a;
cin >> a;
numbers = new unsigned[a];
}

如何使用2d数组(从用户处读取大小为a*b的数组(?

如果a和b分别是行数和列数,则可以如下分配数组:

new unsigned[a * b];

要访问i行和j列的元素,请执行以下操作:

numbers[i * b + j]

然而,请注意,在现实中,无论你想做什么,你几乎肯定会更好地使用std::vector,但你可能还没有了解这一点:(

任何在代码中看起来像2D阵列的东西都不会是内存中的物理2D阵列,而是一个普通的内存块或分散的,这取决于你如何分配它

  • 你可以通过在另一个由N个指针组成的动态数组中动态分配N个数组来折磨自己,就像nrussel的答案所建议的那样
  • 相反,你可以像billz和Arun C.B建议的那样,制作一个向量的向量,这将减轻你自己管理分配的内存的负担,但仍然会给你留下N+1个分散的分配,这不是很好的性能
  • Brennan Vincent的答案建议分配一个动态数组,其中包含a*b元素,这将在内存中提供一个连续的块。结合他提到的std::vector的内置动态内存管理,很高兴:

    std::vector<unsigned> matrix(a*b);

如果您希望矩阵便于访问,请将整个矩阵封装到一个类中,以便访问具有二维坐标的元素。但请不要自己管理记忆。这只会伤害你和任何必须维护代码(并搜索内存泄漏(的人。

可以只使用一个向量来表示二维数组:

   typedef std::vector<int>     d1_type;       // 1D
   typedef std::vector<d1_type> d2_type;       // 2D
   typedef std::vector<d2_type> d3_type;       // 3D

   int num = 5;
   d2_type value2d(num, d1_type(num));
   d3_type value3d(num, d2_type(num, d1_type(num)));

您可以访问2D/3D矢量状阵列,例如:

 value2d[0][0] = 100;
 value3d[0][0][0] = 100;

更新建议:

值得注意的是,boost已经做到了这一点所以,如果它不是要封装在一个类中,我会坚持使用它。

原答覆:

通常,使用原始数组和分配不如使用std::vector。现在,您当然可以使用vector<vector<T>>,但这不仅打字很长,而且可能涉及不必要的复制。

使用ptr_vectorvector<unique_ptr<vector<int>>可以解决第二个问题,但会使问题更加复杂。那么如何解决呢?

很简单:根本不使用2D数组

想象一下你在内存中的2D阵列:

[X|X|X|X]
[Y|Y|Y|Y]
[Z|Z|Z|Z]

很明显,它可以放在一排:

[X|X|X|X|Y|Y|Y|Y|Z|Z|Z|Z]

现在我们回到老的、熟悉的1D数组(不管是vector还是C样式的数组(。为了获得元素,您必须知道初始数组的宽度,并转到第n行对应的数组元素,然后简单地添加列数:

int& access (unsigned x, unsigned y) { 
    return data[x * sizeY + y]; // Or (y * sizeX + x)
}

由于它是一个存根方法,您在实际使用中可能会遇到问题。下面是一个全局实现的例子:

int& accessVectorAs2d (std::vector<int> & data, unsigned x, unsigned y, unsigned int sizeY); // inside stays the same
unsigned SizeX = 20, SizeY = 20;
std::vector<int> V (SizeX * SizeY, 0);
accessVectorAs2d(V, 1, 3, SizeX) = 5;

返回参考以允许以与正常2D阵列非常相似的方式使用1D结构:

// So you can do either reads
int X = access(1, 3);
// Or writes!
access(1,3) = 5;

附加说明:如果您要构建自己的类,重载operator()可以给您更好的结果:

Data(1, 3) = 5;
int X = Data(1, 3);

现在,如何实现该访问(子类化或封装向量,或者只使用普通的全局函数(并不重要。

我强烈建议您在这里使用std::vector。它将确保没有内存泄漏(忘记删除(,更容易更改大小(通过.push_back().reserve()(,这是通常建议的做法;毕竟,你是用C++写的,而不是用C写的。

瞧!龙在这一点之后

事实上,类当然应该是模板化的,不仅要有类型,还要有维度的数量(好吧,可以简化(和(每-1(维度的大小(-1允许在一侧无限增长(。最好是在编译时创建适当的访问函数,计算

总和i=0i<n(大小i(i*Di

其中n是维度的数量,S是维度大小的数组,D是坐标的数组。

尝试使用矢量。

#include <iostream>
#include <vector>
using namespace std;
int main()
{
// An empty vector of vectors. The space 
// between the 2 '>' signs is necessary
vector<vector<int> > v2d;
// If you intend creating many vectors 
// of vectors, the following's tidier
  typedef vector<vector<int> > IntMatrix;
  IntMatrix m;
// Now we'll try to create a 3 by 5 "matrix".
// First, create a vector with 5 elements
   vector<int> v2(5, 99); 
// Now create a vector of 3 elements. 
 // Each element is a copy of v2
 vector<vector<int> > v2d2(3,v2);
// Print out the elements
 for(int i=0;i<v2d2.size(); i++) {
  for (int j=0;j<v2d2[i].size(); j++)
    cout << v2d2[i][j] << " "; 
    cout << endl;
   }
}

您可以通过以下方式使用c++new[]来分配内存:

int** array = new int*[x];
for(int i = 0; i < x; i++)
    aryay[i] = new int[y];

它的简单概念是它和指向数组的指针数组。它也必须删除以避免内存泄漏。

尽管"矢量中的矢量"解决方案可以令人满意,但它们不是2D结构:每个"行"将独立于另一行进行分配,并且长度可以按原始行不同(因此必须手动维护2D约束:插入项需要放大所有行,以便一个在另一个之上的元素保持其相对位置。

如果你需要一个合适的动态2D结构,你可以将一个向量(简单的一维(包装在一个类中(让我们称之为"table"(,并为该类提供所需的操作,以将其正确地保持为外部表示的2D。特别是:

  • 定义Colums() constRows() const函数以重新调整表的实际大小
  • 定义int& operator()(unsigned row, unsigned col) { return vect[row*Colums()+col]; }及其常量对应项
  • 定义一个struct coord { unsigned r, unsigned c }和一个方便的table::operator[](const coord&)
  • 定义insertremove方法来插入一行(只需在r*Columns()处插入Colums()连续元素(和一列(从c开始,每Columns()+1插入一个元素(
  • 定义适当的迭代器类,这些类沿着列(++按1元素前进(和行(++按Columbs((元素前进((注意为它们一致地定义end()值(

这一切的关键是在第二点上对CCD_ 28公式的理解。其他一切几乎都是立竿见影的结果。

unsigned **numbers;
numbers = new unsigned*[a];
for (int i=0; i<a; i++){
    numbers[i] = new unsigned[b];
}

它的行为并不完全像2d数组,因为它在内存中不是连续的,但它会这样做。你也可以使用符号numbers[i][j]来访问元素。

记住delete[] numbers的每个元素在delete[]之前的末尾都是numbers本身

使用std::vector可能是一个更好的解决方案,如其他文章

所述

相关内容

  • 没有找到相关文章

最新更新