Pointer-to-pointer dynamic two-dimensional array

后端 未结 5 1779
庸人自扰
庸人自扰 2020-11-28 03:56

First timer on this website, so here goes..

I\'m a newbie to C++ and I\'m currently working through the book \"Data structures using C++ 2nd ed, of D.S. Malik\".

相关标签:
5条回答
  • 2020-11-28 04:13

    The first method cannot be used to create dynamic 2D arrays because by doing:

    int *board[4];
    

    you essentially allocated an array of 4 pointers to int on stack. Therefore, if you now populate each of these 4 pointers with a dynamic array:

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

    what you end-up with is a 2D array with static number of rows (in this case 4) and dynamic number of columns (in this case 10). So it is not fully dynamic because when you allocate an array on stack you should specify a constant size, i.e. known at compile-time. Dynamic array is called dynamic because its size is not necessary to be known at compile-time, but can rather be determined by some variable in runtime.

    Once again, when you do:

    int *board[4];
    

    or:

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

    you supply a constant known at compile-time (in this case 4 or x) so that compiler can now pre-allocate this memory for your array, and when your program is loaded into the memory it would already have this amount of memory for the board array, that's why it is called static, i.e. because the size is hard-coded and cannot be changed dynamically (in runtime).

    On the other hand, when you do:

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

    or:

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

    the compiler does not know how much memory board array will require, and therefore it does not pre-allocate anything. But when you start your program, the size of array would be determined by the value of x variable (in runtime) and the corresponding space for board array would be allocated on so-called heap - the area of memory where all programs running on your computer can allocate unknown beforehand (at compile-time) amounts memory for personal usage.

    As a result, to truly create dynamic 2D array you have to go with the second method:

    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
    }
    

    We've just created an square 2D array with 10 by 10 dimensions. To traverse it and populate it with actual values, for example 1, we could use nested loops:

    for (int i = 0; i < 10; ++i) {   // for each row
      for (int j = 0; j < 10; ++j) { // for each column
        board[i][j] = 1;
      }
    }
    
    0 讨论(0)
  • 2020-11-28 04:15

    What you describe for the second method only gives you a 1D array:

    int *board = new int[10];
    

    This just allocates an array with 10 elements. Perhaps you meant something like this:

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

    In this case, we allocate 4 int*s and then make each of those point to a dynamically allocated array of 10 ints.

    So now we're comparing that with int* board[4];. The major difference is that when you use an array like this, the number of "rows" must be known at compile-time. That's because arrays must have compile-time fixed sizes. You may also have a problem if you want to perhaps return this array of int*s, as the array will be destroyed at the end of its scope.

    The method where both the rows and columns are dynamically allocated does require more complicated measures to avoid memory leaks. You must deallocate the memory like so:

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

    I must recommend using a standard container instead. You might like to use a std::array<int, std::array<int, 10> 4> or perhaps a std::vector<std::vector<int>> which you initialise to the appropriate size.

    0 讨论(0)
  • 2020-11-28 04:17

    This code works well with very few requirements on external libraries and shows a basic use of int **array.

    This answer shows that each array is dynamically sized, as well as how to assign a dynamically sized leaf array into the dynamically sized branch array.

    This program takes arguments from STDIN in the following format:

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

    Code for program below...

    #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;
    }
    

    It's a very simple implementation of int main and relies solely on std::cin and std::cout. Barebones, but good enough to show how to work with simple multidimensional arrays.

    0 讨论(0)
  • 2020-11-28 04:27

    In both cases your inner dimension may be dynamically specified (i.e. taken from a variable), but the difference is in the outer dimension.

    This question is basically equivalent to the following:

    Is int* x = new int[4]; "better" than int x[4]?

    The answer is: "no, unless you need to choose that array dimension dynamically."

    0 讨论(0)
  • 2020-11-28 04:34

    this can be done this way

    1. I have used Operator Overloading
    2. Overloaded Assignment
    3. Overloaded Copy Constructor

      /*
       * 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;
      }
      
    0 讨论(0)
提交回复
热议问题