嗨,我是C ++的新手,我需要动态分配二维数组。没有错误,但是在运行时,当我设置顺序和第一行时,我得到了运行时错误:“分段错误” ...这里的代码:
#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;
}
您忘记在初始化循环中增加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次呼叫。
替换
double ** arr = new double *[order];
for(int i = 0;i < order; i++){
*arr = new double[order+1];
with
double ** arr = new double *[order];
for(int i = 0;i < order; i++){
arr[i] = new double[order+1];
在您当前的代码中,您仅初始化第一个数组元素。