Passing pointer to an array into a function

I'm an experienced coder but relatively new to C++. I took a C course maybe 35 years ago but have worked with it only sparingly since.

I read the "read before posting!" post and have looked at multiple forums, tried Googling (but get answers to different questions), tried moving the array in question into the global area or inside main(), etc.

My issue:
I'm trying to pass a pointer to an array into a function and have the function be able to manipulate the array. This way I could have any array with identical properties but completely different data or number of elements and be able to perform the same operations on each array.

However when I pass a pointer to the function, it doesn't calculate the dimension of the array correctly. I'm trying to use sizeof(arr) to get the total length of the array and sizeof(arr[0]) to get the length of one element, then use sizeof(arr)/sizeof(arr[0]) to calculate the number of elements in the array for purposes of iteration.

In this example when I run the 3 "cout <<" statements inside main() it produces the correct results. When I initialize a pointer to the address of the array and pass the pointer to the function, it apparently only "sees" the first 2 elements of the array.

What am I doing wrong or isn't this possible using pointers?

/* ------------------------------------------------------------*/

#include <iostream>
using namespace std;

void exampleArraysize(int* arr) {
cout << "sizeof(arr) is: " <<sizeof(arr) << "\n";
cout << "sizeof(arr[0]) is: " <<sizeof(arr[0]) << "\n";
cout << "The size of the array is: " << sizeof(arr)/sizeof(arr[0]) << endl;
}

int arr[] = {10,20,30,40,50,60};

int main() {
cout << "sizeof(arr) is: " <<sizeof(arr) << "\n";
cout << "sizeof(arr[0]) is: " <<sizeof(arr[0]) << "\n";
cout << "The size of the array is: " << sizeof(arr)/sizeof(arr[0]) << endl;

cout << "\n*** Returns incorrect results when calling a function passing a pointer\n" << endl;

int* ptr;
ptr = &arr[0];
exampleArraysize(ptr);
}

/* --------------------------- Output -------------------------*/


sizeof(arr) is: 24
sizeof(arr[0]) is: 4
The size of the array is: 6

*** Returns incorrect results when calling a function passing a pointer

sizeof(arr) is: 8
sizeof(arr[0]) is: 4
The size of the array is: 2
When a C-style array is passed to a function (in both C and C++), the array degrades into a pointer. This means sizeof(arr) is sizeof(int*), which is the size of a pointer in bytes, not the array.

From main, you can pass sizeof(arr)/sizeof(arr[0]) as a second parameter to whatever function, so that you know the size of the array within a function.

An alternative is to use std::array + templates.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <array>
using namespace std;

template <typename T, size_t N>
void exampleArraysize(const std::array<T, N>& arr) {
    cout << "The size of the array is: " << arr.size() << endl;
}

int main() {
        
    std::array<int, 6> arr = {10,20,30,40,50,60};
    exampleArraysize(arr);
}


Another alternative is to use a vector.
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <vector>
using namespace std;

void exampleArraysize(const std::vector<int>& vec) {
    cout << "The size of the vector is: " << vec.size() << endl;
}

int main() {
        
    std::vector<int> vec = {10,20,30,40,50,60};
    exampleArraysize(vec);
}
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>

using namespace std;

void exampleArraysize(int* arr, size_t sz)
{
    cout
    << "       sizeof(arr) is: " << sizeof(arr[0]) * sz << '\n'
    << "       sizeof(int) is: " << sizeof(int) << '\n'
    << "    sizeof(arr[0]) is: " << sizeof(arr[0]) << '\n'
    << "no. of array elements: " << sz << '\n';
}

int arr[] = {10,20,30,40,50,60};

int main()
{
    cout
    << "       sizeof(arr) is: " << sizeof(arr) << '\n'
    << "       sizeof(int) is: " << sizeof(int) << '\n'
    << "    sizeof(arr[0]) is: " << sizeof(arr[0]) << '\n'
    << "no. of array elements: " << sizeof(arr)/sizeof(int) << '\n';
    
    
    cout << "\n*** Returns incorrect results when calling a function passing a pointer\n" << endl;
    
    int* ptr;
    ptr = arr;
    exampleArraysize(ptr, sizeof(arr)/sizeof(int) );
}


       sizeof(arr) is: 24
       sizeof(int) is: 4
    sizeof(arr[0]) is: 4
no. of array elements: 6

*** Returns incorrect results when calling a function passing a pointer

       sizeof(arr) is: 24
       sizeof(int) is: 4
    sizeof(arr[0]) is: 4
no. of array elements: 6
Program ended with exit code: 0
caseyscherm wrote:
I'm an experienced coder but relatively new to C++. I took a C course maybe 35 years ago but have worked with it only sparingly since.


Just something to help you out a little:

Be aware that C++ is a multi paradigm language: it requires a different way of thinking compared to C. I too learnt C from K&R in 1988, I had to change my thinking quite a bit while learning C++. Also, there is a new standard for C++ every 3 years, the next one is due in 2023, compiler vendors have already implemented some C++23 items. So this means that extra facilities are added each 3 years, the language and it's standard library has evolved quite a lot since 2011. C has evolved has well, perhaps not to the same extent as C++ though.

One can of course write C code, but it is better to make use of the C++ STL (Standard Template Library) and use the containers and algorithms found there. Also very handy are range based for loops, for when one wants to iterate through the entire container. So this means that one perhaps need not to worry about the container size as much.

People often fall into the trap of doing C type things like using pointers and C arrays everywhere, and looping through each char in a string. The C++ way is to use references instead of pointers (they behave in a similar fashion) ; use a container like std::vector instead of a C array or std::string if it's a string; use smart pointers if required; use the STL algorithms or functions that belong to a class, for example std::find.

Here is some links to the aforementioned items on cppreference. Some find this a bit bit technical, but it is the best reference out there in terms of what is in the C++ standards - they don't allow anything not in the standard.

https://en.cppreference.com/w/
https://en.cppreference.com/w/cpp/language
https://en.cppreference.com/w/cpp/language/range-for
https://en.cppreference.com/w/cpp/container/vector
https://en.cppreference.com/w/cpp/memory
https://en.cppreference.com/w/cpp/symbol_index
https://en.cppreference.com/w/cpp/string/basic_string
https://en.cppreference.com/w/cpp/string/basic_string_view
https://en.cppreference.com/w/cpp/compiler_support/20

Good Luck, don't be afraid to ask for help or code reviews - never know what one may learn, even if your program works perfectly, there may be a better way of doing it. :+)
I want to thank Ganado, againtry and TheIdeasMan for their quick and thorough responses. This was my first post here so there may be a better/preferred vehicle for directly thanking a contributor who helps you, but I haven't found it yet.

Again, my sincere thanks.

Casey
You can also pass by templated reference:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

template <size_t SZ>
void exampleArraysize(const int (&arr)[SZ])
{
	std::cout
		<< "       sizeof(arr) is: " << sizeof(arr[0]) * SZ << '\n'
		<< "no. of array elements: " << SZ << '\n';
}

int main()
{
	const int arr[] {10,20,30,40,50,60};

	std::cout
		<< "       sizeof(arr) is: " << sizeof(arr) << '\n'
		<< "no. of array elements: " << sizeof(arr) / sizeof(arr[0]) << '\n';


	std::cout << "\nPassed by template reference\n\n";

	exampleArraysize(arr);
}



       sizeof(arr) is: 24
no. of array elements: 6

Passed by template reference

       sizeof(arr) is: 24
no. of array elements: 6

Topic archived. No new replies allowed.