二维数组C ++的动态分配

时间:2014-12-11 14:24:26

标签: c++ arrays dynamic multidimensional-array allocation

嗨,我对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;
}

2 个答案:

答案 0 :(得分:3)

您忘记在初始化循环中增加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 NULL;  // 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[]两次电话,而不是拨打new[]的10,000次电话。

答案 1 :(得分:1)

替换

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];

在您目前的代码中,您只初始化第一个数组元素。