How to Declare a 2D Array in C++ using new operator?

How to Declare a 2D Array in C++ using new operator?

Answer: Declaring a 2D array using new in C++ is useful in situations like dynamic memory allocation, memory management, and performance optimization.

A 2D (two-dimensional) array is a data structure that stores elements in a grid-like format with rows and columns like a matrix. It is an array of arrays, where each element is itself an array. The grid-like structure of a 2D array is beneficial for storing and manipulating data for matrices, spreadsheets, and game boards. In this article, we’ll discuss about declaring a 2D array in C++ using new.

Declare a 2D Array in C++

Table of Contents:

Methods to Declare a 2D Array in C++ Using New

There are few methods to declare a 2D array in C++ using the new keyword:

Method 1: Using an Array of Pointers to Declare a 2D Array in C++

In C++, a 2D array can be declared by an array of pointers, each referencing a dynamically allocated array (a row). It is one type that provides flexibility to dynamic memory management. 

First, you allocate memory for an array of pointers, then allocate memory for each row. The benefit of this method is that you can allocate different amounts of memory for each row if needed.

Example

#include <iostream>
using namespace std;
int main() {
    int rows = 3, cols = 4;
    //Dynamically allocate memory for an array of row pointers
    int** matrix = new int*[rows];
    for (int i = 0; i < rows; i++) {
        matrix[i] = new int[cols]; 
    }
   //Assign a value to the first element in the first row and print it
    matrix[0][0] = 1; 
    cout << "Value at matrix[0][0]: " << matrix[0][0] << endl;  
    for (int i = 0; i < rows; i++) {
        //deallocate the memory for the row pointers
        delete[] matrix[i];  
   }
    delete[] matrix; 
    return 0;
}

Output:

In this code, it first declares memory space for an array of row pointers, and then for each row, it allocates memory space for the columns. It assigns a value in the first element of the first row and prints it. Then deallocates the memory to avoid memory leaks by using `delete[ ]` for each row and then for the array of row pointers.

Method 2: Using a Single Contiguous Block of Memory to Declare a 2D Array in C++

A dynamic 2D array consisting of a single block of memory contains all the elements in a single large block of memory, instead of memory allocation row by row. The elements are stored in row-major order, i.e. the entire first row is stored first, followed by the second row, and so on. 

Example

#include <iostream>
using namespace std;
int main() {
    int m = 3;
    int n = 4;

//Allocate a contiguous block of memory for the entire array   
int* array = new int[m * n];
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            array[i * n + j] = (i + 1) * (j + 1);  
        }
    }

    //Printing 2D array
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            cout << array[i * n + j] << " ";
        }
        cout << endl;
    }
    delete[] array;
    return 0;
}

Output: 

In this approach, we treat the 2D array as a 1D array using the formula array[i * n + j] to access the element at row i and column j.

Method 3: Using Smart Pointers to Declare a 2D Array in C++

This method is a modern approach to declare a dynamic memory allocation in C++, by using smart pointers like unique_ptr and shared_ptr to automatically manage the memory and deallocate if no longer needed.

Example: 

#include <iostream>
#include <memory>
using namespace std;
int main() {
    int m = 3;  
    int n = 4; 
    //Create a unique pointer for the 2D array
    std::unique_ptr<std::unique_ptr<int[]>[]> array(new std::unique_ptr<int[]>[m]);

    //Allocate memory for each row
    for (int i = 0; i < m; ++i) {
        array[i] = std::make_unique<int[]>(n); 
    }

    //modifying elements
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            array[i][j] = (i + 1) * (j + 1);  
        }
    }

   //Print the 2D array
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            cout << array[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

Output:

Comparison of Different Methods to Declare 2D Array in C++

MethodMemory LayoutFlexibilityPerformance
Array of PointersRow-by-rowHighSlower (fragmented memory)
Single Contiguous BlockSingle blockFixed-sizeFaster (cache-friendly)
Smart PointersRow-by-rowHigh (automated deallocation)Moderate

Best Practices of 2D Arrays

  • Always Free Memory that is Allocated: When using the new method of 2D arrays, keep in mind to use the delete[ ] function to free the memory in order to make sure there is no memory leak.
  • Prefer Smart Pointers: For automatic memory management you only need to use smart pointers std::unique_ptr or std::shared_ptr in order to reduce the chances of memory leaks of any kind.
  • Allocate Only When Necessary: Always avoid any unnecessary memory allocations in order to keep memory usage efficient.
  • Use std::vector whenever possible: Standard C++’s std::vector<std::vector<int>> is preferable today because it automatically handles memory management, but also has built-in resizing features.

Real-World Use Cases

  • Game Development: 2D arrays are generally extremely useful for maps of tiles, games of boards, and much more.
  • Machine Learning and Data Science: They are mostly used in diverse matrix operations, neural networks, and handling images only to efficiently store datasets and improve them.
  • Database Systems: 2D Arrays also help to maintain multi-dimensional tables of data, which only improves the overall retrieval of data.
  • Computer Graphics: Employed within frame buffers and rendering pipelines to store values of pixels to permit real-time computation of computer graphics.
  • Simulation and scientific computing: They are most important for finite-element analysis, weather modeling, and physics-based modeling, where big grids need to be employed to make calculations.

Conclusion 

Declaring a 2D array in C++ by using the new keyword generally provides flexibility for dynamic memory management that simply allows efficient memory allocation during runtime. In this article, we have discussed the three methods to declare a 2d array in C++ that is an array of pointers, a single contiguous block, and smart pointers. We have also discussed the best practices and real-world use cases of 2D arrays that will help you to understand this concept better. Learning these approaches helps ensure better memory management, and performance when working with dynamic 2D arrays in C++.

About the Author

Senior Consultant Analytics & Data Science

Sahil Mattoo, a Senior Software Engineer at Eli Lilly and Company, is an accomplished professional with 14 years of experience in languages such as Java, Python, and JavaScript. Sahil has a strong foundation in system architecture, database management, and API integration. 

fullstack