二维数组C++的动态分配
Posted
技术标签:
【中文标题】二维数组C++的动态分配【英文标题】:Dynamic Allocation of two-dimensional array C++ 【发布时间】:2015-02-10 01:42:30 【问题描述】:您好,我是 C++ 新手,我需要动态分配二维数组。没有错误,但在运行时,当我设置订单和第一行时,我得到一个运行时错误:“Segmentation Fault”......这是代码:
#include <iostream>
using namespace std;
double ** allocateDynamicArray(int &order)
double ** arr = new double *[order];
for(int i = 0;i < order; i++)
*arr = new double[order+1];
return arr;
void deallocateDynamicArray(double **arr, int order)
for(int i=0; i<order; i++)
delete [] arr[i];
delete [] arr;
void addAndPrintArray(double **arr, int order)
cout << "Zadejte prvky pole radu " << order << endl;
for(int i=0; i< order; i++)
for(int j=0; j< order+1; j++)
cout << "Pole[" << i << "][" << j << "]: ";
cin >> arr[i][j];
for(int i=0; i< order; i++)
for(int j=0; j< order+1; j++)
cout << arr[i][j] << " ";
if(arr[i][j] < 10 && arr[i][j] > -10)
cout << " ";
cout << endl;
int main()
int order;
cin >> order;
double **dynArray = allocateDynamicArray(order);
addAndPrintArray(dynArray, order);
deallocateDynamicArray(dynArray, order);
return 0;
【问题讨论】:
使用vector<vector<double>>
几乎肯定会更好。使用起来不那么复杂,因为没有分配/释放问题。
*arr =
应该是arr[i] =
是的,但如果我想使用它怎么办?我只需要知道这段代码有什么不好...
不应该使用它的一个原因是没有检查 new[] 是否在该循环中的任何地方失败。如果失败,则由于new[]
抛出异常而导致内存泄漏。
好的,所以我只需要使用这个:arr[i]
还是总是使用向量?
【参考方案1】:
您忘记在初始化循环中增加 arr
:
for(int i = 0;i < order; i++)
*arr = new double[order+1];
改为这样做:
for(int i = 0;i < order; i++)
arr[i] = new double[order+1];
此外,除非您要更改其中一行的尺寸,否则与分配二维数组的这种方式相比,上述方法效率低:
double ** allocateDynamicArray(int &order)
double ** arr = new double *[order];
int cols = order+1;
double *pool = new double [order * cols];
for(int i = 0;i < order; i++, pool += cols)
arr[i] = pool;
return arr;
void deallocateDynamicArray(double **arr)
delete [] arr[0];
delete [] arr;
只需调用两次new[]
和两次调用delete[]
,无论行数和列数如何。
上述第二种形式优于第一种形式的另一个原因是new[]
可能会引发异常。
使用第一种形式,如果在循环中的某处,new[]
抛出异常,您必须跟踪所有先前成功的分配,并通过发出 delete[]
调用“回滚”它们。不好看。
使用第二种形式,如果对new[]
的第一次调用失败,则不会有任何危害,因为将抛出异常而不会泄漏(因为没有成功分配内存)。如果对new[]
的第二次调用失败,您需要做的就是提供(在catch
块内)删除对new[]
的第一次调用。
double ** allocateDynamicArray(int &order)
double ** arr = new double *[order];
int cols = order+1;
try
double *pool = new double [order * cols];
catch (std::bad_alloc& e)
delete [] arr; // delete previous allocation
return nullptr; // or rethrow the exception here
for(int i = 0;i < order; i++, pool += cols)
arr[i] = pool;
return arr;
请注意,std::vector
会为您完成所有这些工作。但是,如果由于某种原因您不能使用向量,并且二维数组在其整个生命周期中将保持相同的大小,请使用第二种形式。
另外,第二种方法减少了堆的内存碎片。代替rows
调用分配器,只调用分配器来分配数据。如果 rows
是 1,000 或 10,000,您会立即看到最好对 new[]
进行 2 次调用,而不是对 new[]
进行 10,000 次调用。
【讨论】:
谢谢,这就是我想要的。 :D【参考方案2】:替换
double ** arr = new double *[order];
for(int i = 0;i < order; i++)
*arr = new double[order+1];
与
double ** arr = new double *[order];
for(int i = 0;i < order; i++)
arr[i] = new double[order+1];
在您当前的代码中,您只初始化第一个数组元素。
【讨论】:
以上是关于二维数组C++的动态分配的主要内容,如果未能解决你的问题,请参考以下文章