指针指针动态二维数组

时间:2013-04-14 17:09:47

标签: c++ arrays pointers memory-management dynamic-arrays

本网站上的第一个计时器,所以这里......

我是C ++的新手,我目前正在阅读“使用C ++第二版,D.S.Malik的数据结构”一书。

在书中,Malik提供了两种创建动态二维数组的方法。 在第一种方法中,将变量声明为指针数组,其中每个指针都是整数类型。离。

int *board[4];

..然后使用for循环创建'columns',同时将指针数组用作'rows'。

第二种方法是使用指向指针的指针。

int **board;
board = new int* [10]; 

我的问题是:哪种方法更好? **方法对我来说更容易可视化,但第一种方法可以大致相同的方式使用。两种方式都可用于制作动态二维数组。

编辑:上述帖子不够清楚。这是我尝试的一些代码:

int row, col;

cout << "Enter row size:";
cin >> row;
cout << "\ncol:";
cin >> col;

int *p_board[row];
for (int i=0; i < row; i++)
    p_board[i] = new int[col];

for (int i=0; i < row; i++)
{
    for (int j=0; j < col; j++)
    {
        p_board[i][j] = j;
        cout << p_board[i][j] << " ";
    }
    cout << endl;
}
cout << endl << endl;

int **p_p_board;
p_p_board = new int* [row];
for (int i=0; i < row; i++)
    p_p_board[i] = new int[col];

for (int i=0; i < row; i++)
{
    for (int j=0; j < col; j++)
    {
        p_p_board[i][j] = j;
        cout << p_p_board[i][j] << " ";
    }
    cout << endl;
}

5 个答案:

答案 0 :(得分:40)

第一种方法不能用于创建动态 2D数组,因为这样做:

int *board[4];

你实际上已经在堆栈上分配了一个包含int 的4个指针的数组。因此,如果您现在使用动态数组填充这4个指针中的每一个:

for (int i = 0; i < 4; ++i) {
  board[i] = new int[10];
}

你最终得到的是一个2D阵列,其中静态行数(在本例中为4)和动态列数(在本例中为10)。所以它不是完全动态,因为当您在堆栈上分配数组时,指定常量,即编译 - 时间即可。 动态数组称为动态,因为其大小无需在编译时中获知,但可以由<中的某个变量确定强>运行时

再一次,当你这样做时:

int *board[4];

或:

const int x = 4; // <--- `const` qualifier is absolutely needed in this case!
int *board[x];

你提供一个在编译时(在本例中为4或x)已知的常量,以便编译器现在可以预先分配这个内存供您使用数组,当你的程序被加载到内存中时,board数组已有这么多的内存,这就是为什么它被称为静态,即因为大小为硬编码无法动态更改(在运行时)。

另一方面,当你这样做时:

int **board;
board = new int*[10];

或:

int x = 10; // <--- Notice that it does not have to be `const` anymore!
int **board;
board = new int*[x];

编译器不知道数组需要多少内存board,因此它不会预先分配任何内容。但是当你启动你的程序时,数组的大小将由x变量的值(在运行时)确定,并且board数组的相应空间将分配在所谓的堆上 - 计算机上运行的所有程序可以预先分配未知(在编译时)的内存区域,用于个人使用。

因此,要真正创建动态2D数组,您必须使用第二种方法:

int **board;
board = new int*[10]; // dynamic array (size 10) of pointers to int

for (int i = 0; i < 10; ++i) {
  board[i] = new int[10];
  // each i-th pointer is now pointing to dynamic array (size 10) of actual int values
}

我们刚刚创建了一个10×10维的正方形2D数组。要遍历它并用实际值填充它,例如1,我们可以使用嵌套循环:

for (int i = 0; i < 10; ++i) {   // for each row
  for (int j = 0; j < 10; ++j) { // for each column
    board[i][j] = 1;
  }
}

答案 1 :(得分:6)

您为第二种方法描述的内容仅为您提供一维数组:

int *board = new int[10];

这只是分配一个包含10个元素的数组。也许你的意思是这样的:

int **board = new int*[4];
for (int i = 0; i < 4; i++) {
  board[i] = new int[10];
}

在这种情况下,我们分配4个int*,然后使每个指向动态分配的10 int个数组。

所以现在我们将其与int* board[4];进行比较。主要区别在于,当您使用这样的数组时,必须在编译时知道“行”的数量。那是因为数组必须具有编译时固定大小。如果您想要返回此int*数组,也可能会出现问题,因为数组将在其范围的末尾被销毁。

动态分配行和列的方法确实需要更复杂的措施来避免内存泄漏。你必须像这样解除内存:

for (int i = 0; i < 4; i++) {
  delete[] board[i];
}
delete[] board;

我必须建议使用标准容器。您可能希望使用初始化为适当大小的std::array<int, std::array<int, 10> 4>std::vector<std::vector<int>>

答案 2 :(得分:1)

在这两种情况下,您的内部维度可以动态指定(即从变量中获取),但差异在外部维度。

这个问题基本上等同于以下内容:

  

int* x = new int[4];“比int x[4]更好”吗?

答案是:“,除非您需要动态选择该数组维度。”

答案 3 :(得分:0)

此代码适用于外部库的极少要求,并显示int **array的基本用法。

这个答案显示每个数组是动态调整大小的,以及如何将动态大小的叶子数组分配到动态大小的分支数组中。

该程序以下列格式从STDIN获取参数:

2 2   
3 1 5 4
5 1 2 8 9 3
0 1
1 3

以下程序代码......

#include <iostream>

int main()
{
    int **array_of_arrays;

    int num_arrays, num_queries;
    num_arrays = num_queries = 0;
    std::cin >> num_arrays >> num_queries;
    //std::cout << num_arrays << " " << num_queries;

    //Process the Arrays
    array_of_arrays = new int*[num_arrays];
    int size_current_array = 0;

    for (int i = 0; i < num_arrays; i++)
    {
        std::cin >> size_current_array;
        int *tmp_array = new int[size_current_array];
        for (int j = 0; j < size_current_array; j++)
        {
            int tmp = 0;
            std::cin >> tmp;
            tmp_array[j] = tmp;
        }
        array_of_arrays[i] = tmp_array;
    }


    //Process the Queries
    int x, y;
    x = y = 0;
    for (int q = 0; q < num_queries; q++)
    {
        std::cin >> x >> y;
        //std::cout << "Current x & y: " << x << ", " << y << "\n";
        std::cout << array_of_arrays[x][y] << "\n";
    }

    return 0;
}

这是int main的一个非常简单的实现,仅依赖于std::cinstd::cout。准系统,但足以说明如何使用简单的多维数组。

答案 4 :(得分:0)

这可以通过这种方式完成

  1. 我使用过运算符重载
  2. 分配超载
  3. 重载的副本构造方法

    /*
     * Soumil Nitin SHah
     * Github: https://github.com/soumilshah1995
     */
    
    #include <iostream>
    using namespace std;
            class Matrix{
    
    public:
        /*
         * Declare the Row and Column
         *
         */
        int r_size;
        int c_size;
        int **arr;
    
    public:
        /*
         * Constructor and Destructor
         */
    
        Matrix(int r_size, int c_size):r_size{r_size},c_size{c_size}
        {
            arr = new int*[r_size];
            // This Creates a 2-D Pointers
            for (int i=0 ;i < r_size; i++)
            {
                arr[i] = new int[c_size];
            }
    
            // Initialize all the Vector to 0 initially
            for (int row=0; row<r_size; row ++)
            {
                for (int column=0; column < c_size; column ++)
                {
                    arr[row][column] = 0;
                }
            }
            std::cout << "Constructor -- creating Array Size ::" << r_size << " " << c_size << endl;
        }
    
        ~Matrix()
        {
            std::cout << "Destructpr  -- Deleting  Array Size ::" << r_size <<" " << c_size << endl;
    
        }
    
        Matrix(const Matrix &source):Matrix(source.r_size, source.c_size)
    
        {
            for (int row=0; row<source.r_size; row ++)
            {
                for (int column=0; column < source.c_size; column ++)
                {
                    arr[row][column] = source.arr[row][column];
                }
            }
    
            cout << "Copy Constructor " << endl;
        }
    
    
    public:
        /*
         * Operator Overloading
         */
    
        friend std::ostream &operator<<(std::ostream &os, Matrix & rhs)
        {
            int rowCounter = 0;
            int columnCOUNTER = 0;
            int globalCounter = 0;
    
            for (int row =0; row < rhs.r_size; row ++)
            {
                for (int column=0; column < rhs.c_size ; column++)
                {
                    globalCounter = globalCounter + 1;
                }
                rowCounter = rowCounter + 1;
            }
    
    
            os << "Total There are " << globalCounter << " Elements" << endl;
            os << "Array Elements are as follow -------" << endl;
            os << "\n";
    
            for (int row =0; row < rhs.r_size; row ++)
            {
                for (int column=0; column < rhs.c_size ; column++)
                {
                    os << rhs.arr[row][column] << " ";
                }
            os <<"\n";
            }
            return os;
        }
    
        void operator()(int row, int column , int Data)
        {
            arr[row][column] = Data;
        }
    
        int &operator()(int row, int column)
        {
            return arr[row][column];
        }
    
        Matrix &operator=(Matrix &rhs)
                {
                    cout << "Assingment Operator called " << endl;cout <<"\n";
                    if(this == &rhs)
                    {
                        return *this;
                    } else
                        {
                        delete [] arr;
    
                            arr = new int*[r_size];
                            // This Creates a 2-D Pointers
                            for (int i=0 ;i < r_size; i++)
                            {
                                arr[i] = new int[c_size];
                            }
    
                            // Initialize all the Vector to 0 initially
                            for (int row=0; row<r_size; row ++)
                            {
                                for (int column=0; column < c_size; column ++)
                                {
                                    arr[row][column] = rhs.arr[row][column];
                                }
                            }
    
                            return *this;
                        }
    
                }
    
    };
    
                int main()
    {
    
        Matrix m1(3,3);         // Initialize Matrix 3x3
    
        cout << m1;cout << "\n";
    
        m1(0,0,1);
        m1(0,1,2);
        m1(0,2,3);
    
        m1(1,0,4);
        m1(1,1,5);
        m1(1,2,6);
    
        m1(2,0,7);
        m1(2,1,8);
        m1(2,2,9);
    
        cout << m1;cout <<"\n";             // print Matrix
        cout << "Element at Position (1,2) : " << m1(1,2) << endl;
    
        Matrix m2(3,3);
        m2 = m1;
        cout << m2;cout <<"\n";
    
        print(m2);
    
        return 0;
    }