How to Return Pointer to Array in C++

Jinku Hu Feb 02, 2024
  1. Use int var[n] Notation to Pass the Array Argument to Function and Then Return in C++
  2. Use int* var Notation to Pass the Array Argument to Function and Then Return in C++
  3. Return a Pointer to a Dynamically Allocated Array in C++
  4. Return a Pointer to a Static Array (Not Recommended)
  5. Pass an Array as a Parameter to Modify It
  6. Use std::array or std::vector for Flexibility
  7. Conclusion
How to Return Pointer to Array in C++

Returning a pointer to an array from a function in C++ is a powerful technique that allows for efficient manipulation and management of array data. This approach provides flexibility in handling arrays, enabling functions to modify array elements directly and allowing dynamic memory allocation for arrays whose sizes might not be known at compile time.

In C++, arrays are typically passed by reference as pointers, and returning a pointer to an array from a function empowers developers to perform various operations on arrays while ensuring memory efficiency and optimal performance.

This article explores several methodologies and best practices involved in returning pointers to arrays from functions, elucidating their applications, advantages, and considerations within the C++ programming paradigm.

Use int var[n] Notation to Pass the Array Argument to Function and Then Return in C++

The int var[n] notation in C++ is used to declare an array of integers named var with a fixed size of n. This notation helps define an array and allocates contiguous memory locations to store n integer elements.

Here’s the syntax breakdown:

  • int: Specifies the data type of the array elements (in this case, integers).
  • var: Name of the array.
  • [n]: Indicates the size of the array, where n is a non-negative integer constant or a constant expression representing the number of elements in the array.

Since the function needs to return the pointer value, we will assume that the array is fixed-length. Alternatively, if we have to pass a dynamic array - std::vector to a function, it’s better to use references.

The next example demonstrates the subtractArray function that subtracts each value in the array given the subtrahend value. The array is declared as a raw C-style array, which is mostly useful for operating with pointers.

The array is passed with the int arr[] notation of the parameter, but it is converted underneath by the compiler as the pointer to the array, and we can treat it as such in the function body. Finally, it returns the pointer value directly using the variable name without taking its address with the & operator.

The subtracted array elements are outputted to the console, and after outputting the last element, there is the cout statement that includes \b\b in the string literal. This escape sequence means the backspace key behavior is emulated, thus deleting the last two characters in the console output.

#include <array>
#include <iostream>

using std::array;
using std::cin;
using std::cout;
using std::endl;
using std::string;

int *subtractArray(int arr[], int size, int subtrahend) {
  for (int i = 0; i < size; ++i) {
    arr[i] -= subtrahend;
  }
  return arr;
}

constexpr int SIZE = 10;

int main() {
  int c_array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  int num = 15;

  int *ptr = subtractArray(c_array, SIZE, num);

  cout << "array1 = [ ";
  for (int i = 0; i < SIZE; ++i) {
    cout << ptr[i] << ", ";
  }
  cout << "\b\b ]" << endl;

  return EXIT_SUCCESS;
}

Output:

array1 = [ -14, -13, -12, -11, -10, -9, -8, -7, -6, -5 ]

Use int* var Notation to Pass the Array Argument to Function and Then Return in C++

Another method for passing the fixed-sized array is to declare a function parameter with int* var notation and return the pointer value after the function body is done processing it.

The syntax int* var in C++ is used to declare a pointer variable. It signifies that the variable var is a pointer to an integer.

Here’s the breakdown of the syntax:

  • int*: This denotes the data type of the variable. In this case, it’s an integer pointer. The asterisk (*) indicates that the variable will store the memory address of an integer.
  • var: This is the name of the pointer variable. You can choose any valid name for your pointer variable.

For instance:

int* ptr;  // Declaring an integer pointer named 'ptr'

This statement declares a pointer named ptr that can hold the memory address of an integer. It’s important to note that the asterisk (*) used in the declaration specifies that ptr is a pointer variable, not a multiplication operation.

The spacing around the asterisk is a matter of style and doesn’t affect the functionality; it can be written as int *ptr; with the same meaning.

Note that the next sample code uses the std::array container and calls the data() method to retrieve the pointer where the array elements are stored. The return statement takes the variable name as in the previous method.

#include <array>
#include <iostream>

using std::array;
using std::cin;
using std::cout;
using std::endl;
using std::string;

int *subtractArray(int *arr, int size, int subtrahend) {
  for (int i = 0; i < size; ++i) {
    arr[i] -= subtrahend;
  }
  return arr;
}

constexpr int SIZE = 10;

int main() {
  array<int, SIZE> arr1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  int num = 15;

  int *ptr2 = subtractArray(arr1.data(), arr1.size(), num);

  cout << "array2 = [ ";
  for (int i = 0; i < SIZE; ++i) {
    cout << ptr2[i] << ", ";
  }
  cout << "\b\b ]" << endl;

  return EXIT_SUCCESS;
}

Output:

array2 = [ -14, -13, -12, -11, -10, -9, -8, -7, -6, -5 ]

The code defines a function subtractArray() that subtracts a given value from each element of an array and returns a pointer to the modified array. It then uses this function to modify a std::array, printing the modified elements.

The program essentially demonstrates modifying array elements using a function and pointer manipulation.

Return a Pointer to a Dynamically Allocated Array in C++

In C++, dynamic memory allocation allows the program to allocate memory at runtime rather than compile time.

The new operator is used to dynamically allocate memory for data structures, such as arrays. Conversely, the delete operator deallocates the memory previously allocated using new.

Example:

#include <iostream>

// Method 1: Returning a pointer to a dynamically allocated array
int* createArray(int size) {
  int* arr = new int[size];
  for (int i = 0; i < size; ++i) {
    arr[i] = i * 10;  // Filling the array with some values for demonstration
  }
  return arr;
}

int main() {
  int size = 5;
  int* arrPtr = createArray(size);

  // Accessing and printing values from the returned array pointer
  for (int i = 0; i < size; ++i) {
    std::cout << arrPtr[i] << " ";
  }

  delete[] arrPtr;  // Deallocate memory to prevent memory leaks
  return 0;
}

To dynamically allocate memory for an array, use the new operator followed by the data type and the array size within square brackets [].

After allocating memory, you can populate the array with values if required. This step is optional and depends on the specific use case.

Return the pointer to the dynamically allocated array from the function. Ensure that the pointer is properly returned and can be accessed after the function’s execution.

It’s crucial to deallocate the memory to prevent memory leaks. Use the delete[] operator to free the dynamically allocated memory once the array is no longer needed.

Output:

0 10 20 30 40

Returning a pointer to a dynamically allocated array allows for flexibility in managing memory and enables the creation of arrays whose size is determined at runtime. However, it’s crucial to handle dynamic memory carefully to avoid memory leaks and undefined behavior.

Static arrays in C++ are arrays with fixed sizes determined at compile-time. They are declared using a fixed-size array notation, such as int arr[SIZE], where SIZE is a constant or a literal specifying the array’s size.

In this example, we define a static array within a function, createStaticArray(). The function returns a pointer to the static array by simply returning the array name.

Access the elements of the static array using the returned pointer. Since static arrays have a fixed memory location and the system manages their memory, there’s no need to deallocate memory for them.

#include <iostream>

// Method 2: Returning a pointer to a static array (Not recommended)
int* createStaticArray() {
  static int arr[] = {10, 20, 30, 40, 50};  // Static array
  return arr;
}

int main() {
  int* arrPtr = createStaticArray();

  // Accessing and printing values from the returned array pointer
  for (int i = 0; i < 5; ++i) {
    std::cout << arrPtr[i] << " ";
  }

  // No need to deallocate memory for a static array
  return 0;
}

Output:

10 20 30 40 50 

However, returning pointers to static arrays isn’t recommended in all scenarios, especially if the function is supposed to create dynamic arrays or if the array’s content needs modification. This is due to static arrays having a fixed size and content, making them less flexible for certain use cases where dynamic behavior is required.

Pass an Array as a Parameter to Modify It

In C++, arrays are typically passed to functions by their memory address (pointer) rather than by value. When an array is passed as a parameter, it decays into a pointer to its first element, enabling functions to access and modify the array elements directly.

Example:

#include <iostream>

// Method 3: Passing an array as a parameter to modify it
void fillArray(int arr[], int size) {
  for (int i = 0; i < size; ++i) {
    arr[i] = i * 10;  // Filling the array with some values for demonstration
  }
}

int main() {
  int size = 5;
  int arr[size];  // Declare the array

  fillArray(arr, size);  // Pass the array to fillArray() to modify it

  // Accessing and printing values from the modified array
  for (int i = 0; i < size; ++i) {
    std::cout << arr[i] << " ";
  }

  return 0;
}

Output:

0 10 20 30 40 

The code exemplifies modifying array elements within a function by passing the array as a parameter. It uses the fillArray function to update the array elements based on their indices multiplied by 10.

After the function call, the main function prints the modified array’s values. This showcases how arrays are passed by reference in C++, enabling changes made within a function to reflect in the calling scope.

Use std::array or std::vector for Flexibility

Utilizing std::array or std::vector to return a pointer to an array from a function in C++ provides flexibility and safety. Both containers offer convenient ways to manage arrays dynamically, allowing for easy manipulation and returning a pointer to the managed array.

  • std::array: Fixed-size array-like container introduced in C++11 with a known size at compile-time.
  • std::vector: Dynamic array-like container that can dynamically resize and manage arrays at runtime.

Example:

#include <array>
#include <iostream>
#include <vector>

// Method 4: Using std::array or std::vector for flexibility
std::array<int, 5>* createStdArray() {
  std::array<int, 5>* arr = new std::array<int, 5>{
      10, 20, 30, 40, 50};  // Dynamically allocated std::array
  return arr;
}

std::vector<int>* createVector() {
  std::vector<int>* vec = new std::vector<int>{
      10, 20, 30, 40, 50};  // Dynamically allocated std::vector
  return vec;
}

int main() {
  std::array<int, 5>* arrPtr = createStdArray();
  std::vector<int>* vecPtr = createVector();

  // Accessing and printing values from the returned array pointers
  for (const auto& val : *arrPtr) {
    std::cout << val << " ";
  }
  std::cout << std::endl;
  for (const auto& val : *vecPtr) {
    std::cout << val << " ";
  }

  delete arrPtr;  // Deallocate memory for std::array pointer
  delete vecPtr;  // Deallocate memory for std::vector pointer

  return 0;
}

Output:

10 20 30 40 50 
10 20 30 40 50 

The code demonstrates the creation of dynamically allocated std::array and std::vector, returning pointers to these arrays from functions, accessing their elements through pointers, and properly deallocating the dynamically allocated memory. It illustrates how to work with dynamically allocated arrays using standard library containers in C++.

Conclusion

The article covers various ways to handle arrays in C++:

  1. Using Fixed-Size Arrays:
    • The int var[n] notation creates fixed-size arrays, allocating contiguous memory for elements.
    • Functions can modify these arrays by treating them as pointers to their first elements.
  2. Pointer Notation for Fixed-Size Arrays:
    • int* var notation declares a pointer variable to an integer, suitable for modifying fixed-size arrays.
    • This method is commonly used with standard library containers like std::array.
  3. Dynamic Memory Allocation:
    • The new operator dynamically allocates memory for arrays at runtime.
    • Proper memory management (delete[]) is crucial to prevent memory leaks.
  4. Static Arrays:
    • Returning pointers to static arrays is discouraged due to their fixed size and content.
  5. Passing Arrays as Parameters:
    • Arrays are passed as pointers to their first elements, enabling function modifications.
  6. Using Standard Library Containers:
    • std::array and std::vector offer flexibility and safety for array management, allowing dynamic resizing and proper memory handling.

Each method has distinct advantages and considerations, empowering developers to choose the most suitable approach for array manipulation based on specific requirements in C++.

Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Related Article - C++ Array