二维数组C++的动态分配 [英] Dynamic Allocation of two-dimensional array C++

查看:32
本文介绍了二维数组C++的动态分配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 C++ 的新手,我需要动态分配二维数组.没有错误,但在运行时,当我设置订单和第一行时,我收到一个运行时错误:分段错误"...这是代码:

Hi I'm pretty new to C++ and I need to dynamicacally allocate two-dimensional array. No error but in runtime when I set a order and first row then I get a runtime error: "Segmentation Fault"...Here's code:

#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 :

You forgot to increment arr in your initialization loop:

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

此外,除非您要更改其中一行的维度,否则与这种分配二维数组的方法相比,上述方法效率低下:

Also, unless your going to change the dimensions of one of the rows, the method above is inefficient compared to this way of allocating a 2 dimensional array:

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[],而不管行数和列数.

Just two calls to new[] and only two calls to delete[] are needed, regardless of the number of rows and columns.

上述第二种形式优于第一种形式的另一个原因是 new[] 可能会抛出异常.

The other reason why the second form above should be favored over the first form is in the case where new[] may throw an exception.

使用第一种形式,如果在该循环中的某处,new[] 抛出异常,您必须跟踪所有先前成功的分配,并通过发出 delete[] 调用.不好看.

Using the first form, if somewhere in that loop, new[] throws an exception, you have to keep track of all of the previous successful allocations, and "roll them back" by issuing delete[] calls. Not nice.

使用第二种形式,如果对 new[] 的第一次调用失败,那么没有坏处,因为将抛出异常而不会泄漏(因为没有成功分配内存).如果对 new[] 的第二次调用失败,您需要做的就是提供(在 catch 块内)对 new 的第一次调用的删除[].

Using the second form, if the first call to new[] fails, then there is no harm as the exception will be thrown without leakage (since no memory was successfully allocated). If the second call to new[] fails, all you need to do is to provide (inside of a catch block) the deletion of the first call to 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 会为您完成所有这些工作.但是,如果由于某种原因您不能使用向量,并且二维数组将在其整个生命周期中保持相同的大小,请使用第二种形式.

Note that std::vector does all of this work for you. However if for some reason you can't use vector, and the two dimensional array will remain the same size throughout its lifetime, use the second form.

此外,第二种方法减少了堆的内存碎片.代替对分配器的 rows 调用,只对分配器进行一次调用来分配数据.如果 rows 是,比如说 1,000 或 10,000,你马上就会看到最好对 new[] 进行 2 次调用,而不是对 new[]<进行 10,000 次调用/代码>.

In addition, the second method lessens memory fragmentation of the heap. Instead of rows calls to the allocator, only one call is made to the allocator to allocate the data. If rows were, say 1,000 or 10,000, you see right away it is better to make 2 calls to new[] instead of 10,000 calls to new[].

这篇关于二维数组C++的动态分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆