Passing An Array Into A Function C++

5 min read

Passing an array into a function in C++ is a fundamental concept that often confuses beginners because arrays behave differently than standard variables like int or double. That's why understanding this mechanism is critical for writing efficient, bug-free code and for mastering memory management in C++. Unlike scalar types, arrays are not passed by value automatically; instead, they decay into pointers. This guide explores the various methods to pass arrays to functions, covering raw arrays, modern C++ containers, and the nuances of size preservation Turns out it matters..

The Core Mechanism: Array Decay

When you pass a raw C-style array to a function, the array decays into a pointer to its first element. Consider this: this is the single most important rule to remember. The function signature void func(int arr[]) is treated identically by the compiler as void func(int* arr). As a result, inside the function, you lose all information about the array's original size. The sizeof operator will return the size of the pointer (typically 4 or 8 bytes), not the size of the entire array The details matter here. That alone is useful..

Consider this basic example:

#include 

void printSize(int arr[]) {
    // arr is actually int* arr
    std::cout << "Size inside function (bytes): " << sizeof(arr) << std::endl;
    // This prints pointer size, NOT array size
}

int main() {
    int numbers[5] = {10, 20, 30, 40, 50};
    std::cout << "Size in main (bytes): " << sizeof(numbers) << std::endl; // Prints 20 (5 * 4 bytes)
    printSize(numbers);
    return 0;
}

Because of this decay, you must pass the size of the array as a separate argument if the function needs to know the bounds. This leads to the classic C-style pattern.

Method 1: Passing with a Size Parameter (Classic C-Style)

This is the traditional approach used in C and legacy C++ codebases. You pass the pointer (the decayed array) and an integer representing the element count.

Syntax:

void processArray(int arr[], int size); // or void processArray(int* arr, int size)

Complete Example:

#include 

// Function accepts pointer and explicit size
void doubleValues(int arr[], int size) {
    for (int i = 0; i < size; ++i) {
        arr[i] *= 2; // Modifies the original array
    }
}

void printArray(const int arr[], int size) {
    // 'const' prevents accidental modification
    for (int i = 0; i < size; ++i) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;
}

int main() {
    int data[] = {1, 2, 3, 4, 5};
    int n = sizeof(data) / sizeof(data[0]); // Calculate size in scope where array exists

    std::cout << "Original: ";
    printArray(data, n);

    doubleValues(data, n);

    std::cout << "Doubled:  ";
    printArray(data, n);

    return 0;
}

Key Takeaways:

  • Modifiability: The function modifies the original array because it operates on the memory address.
  • Safety: Use const in the parameter (const int arr[]) if the function should only read the data. This enables compiler checks against accidental writes.
  • Responsibility: The caller bears the burden of calculating and passing the correct size. Passing the wrong size leads to buffer overflows or logic errors.

Method 2: Passing by Reference to Preserve Size (Modern C++)

If you are using modern C++ (C++11 and later), you can pass a raw array by reference. This prevents decay. The function signature includes the array size as part of the type, allowing the compiler to enforce the size and letting you use sizeof correctly inside the function Still holds up..

It sounds simple, but the gap is usually here.

Syntax:

// Reference to an array of 5 integers
void func(int (&arr)[5]); 

Template Version (Generic Size): To make this flexible for arrays of any compile-time size, use a template parameter for the size.

#include 

// Template deduces the size 'N' automatically
template 
void printSizeAndData(int (&arr)[N]) {
    std::cout << "Size deduced inside function: " << N << " elements" << std::endl;
    std::cout << "Sizeof check: " << sizeof(arr) << " bytes" << stdendl; // Works correctly!
    
    for (size_t i = 0; i < N; ++i) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;
}

int main() {
    int smallArr[3] = {1, 2, 3};
    int largeArr[6] = {10, 20, 30, 40, 50, 60};

    printSizeAndData(smallArr); // N becomes 3
    printSizeAndData(largeArr); // N becomes 6
    
    // printSizeAndData({1,2}); // Error: initializer list not an lvalue array
    return 0;
}

Advantages:

  • Type Safety: The compiler rejects arrays of the wrong size (if not templated) or pointers masquerading as arrays.
  • Size Awareness: sizeof(arr) works correctly; range-based for loops work (for (auto& e : arr)).
  • No Manual Size Passing: The size is part of the function signature (deduced via template).

Limitations:

  • Only works for arrays with compile-time known sizes (stack arrays). It does not work for dynamically allocated arrays (new int[n]) or pointers.

Method 3: Using std::array (The Modern Standard Container)

Since C++11, std::array (header <array>) is the preferred replacement for raw fixed-size arrays. It is a lightweight wrapper that does not decay to a pointer. It knows its own size, supports iterators, and works naturally with the Standard Library algorithms Easy to understand, harder to ignore..

Passing std::array: You can pass it by reference (to avoid copying) or by value (which copies the entire array—expensive for large arrays) Turns out it matters..

#include 
#include 
#include  // for std::sort, etc.

// Pass by const reference for read-only access
void printStdArray(const std::array& arr) {
    std::cout << "Size: " << arr.size() << std::endl; // .size() member function!
    

Easier said than done, but still worth knowing.

// Pass by non-const reference to modify
void modifyStdArray(std::array& arr) {
    for (auto& val : arr) {
        val += 100;
    }
}

int main() {
    // Initialization requires double braces pre-C++17, single braces C++17+
    std::array myArr = {10, 20, 30, 40, 50}; 
    
    printStdArray(myArr);
    modifyStdArray(myArr);
    printStdArray(myArr);
    
    // Works with STL algorithms
    std::sort(myArr.begin(), myArr.end(), std::greater<>()); 
    printStdArray(myArr);

    return 0;
}

Why prefer std::array?

  1. **Value Sem
Just Got Posted

Just Finished

Cut from the Same Cloth

You May Find These Useful

Thank you for reading about Passing An Array Into A Function C++. We hope the information has been useful. Feel free to contact us if you have any questions. See you next time — don't forget to bookmark!
⌂ Back to Home