Arrays in Function Paremeters

How can we pass the actual array in to the function so we can get the actual size in the function??

see:


void foo(float arr[]){
std::cout << sizeof(arr) << std::endl; // this prints out the size of pointer
}

int main(){
float bar[18];
std::cout << sizeof(bar) << std::endl; //this is different from :
foo(bar); // this doesnt give me the actual size;

return 0;
}
With raw arrays you normally pass the size as a second parameter.

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>

void foo(float arr[], int size) {
	std::cout << size << std::endl;
}

int main() {
	const int size = 18;
	float bar[size];
	foo(bar, size);
}


You might want to consider using std::vector (or std::array) which keeps track of its own size.

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <vector>

void foo(std::vector<float>& vec) {
	std::cout << vec.size() << std::endl;
}

int main() {
	std::vector<float> bar(18);
	foo(bar);
}

http://www.cplusplus.com/reference/vector/vector/
Last edited on
any other way without using dynamic arrays?
As I already said, I think you should pass the size as a second argument. If you don't want to define a constant to keep track of the size you can use the std::size instead.

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <iterator> // std::size

void foo(float arr[], int size) {
	std::cout << size << std::endl;
}

int main() {
	float bar[18];
	foo(bar, std::size(bar));
}


If you really don't want to pass the size as an argument you can pass the array by reference, but then the function will only accept an array of a fixed size.

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <iterator> // std::size

void foo(float (&arr)[18]) {
	std::cout << std::size(arr) << std::endl;
}

int main() {
	float bar[18];
	foo(bar);
}


You could also make it work for any size by using templates. This means the compiler will generate a new function for each array size that you pass to foo.

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>

template<int N>
void foo(float (&arr)[N]) {
	std::cout << N << std::endl;
}

int main() {
	float bar[18];
	foo(bar); // calls foo<18>
}
Thanks bro, thats what i was looking for, but just another question,

Like you can declare an array without specifying the size,

int arr[] = {1, 2};

can you do it with actual array class?

std::array<int, ?> arr;
closed account (E0p9LyTq)
can you do it with actual std::array class?

Yes.

In fact it is a requirement, you have to specify the number of elements in a std::array at creation time.

http://en.cppreference.com/w/cpp/container/array

C++17 introduces deduction guides to help create std::arrays.

http://en.cppreference.com/w/cpp/container/array/deduction_guides
Last edited on
It is possible in C++17.

 
std::array arr = {1, 2}; 

Note that the type of arr is std::array<int, 2> which is distinct from every other type std::array<int, n> where n≠2.
How do we know that std::array arr contains "ints"?
Because the values in the initializer list are ints.
good point. But isn't there a simple way to get the actual array into the function??

like in java you would do:

float[] arr
A C-style array is just a sequence of elements, it doesn't contain its size, so if you want to write a function that works with an array of any size you need some additional mechanism to pass the size to the function.
Note that most of these problems goes away if you just use std::vector.
Last edited on
Yes, but if you are familiar with OpenGL, it does not take vectors as paremeters, it wants arrays
any idea?
That's not a problem. std::vector stores its elements in an array. You can use the data() member function to pas it to functions that expects an array.

http://en.cppreference.com/w/cpp/container/vector/data

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>
#include <iterator>
#include <vector> 

void print_array(float arr[], int size) {
	for (int i = 0; i < size; ++i) {
		std::cout << arr[i] << '\n';
	}
}

int main() {
	
	float arr[] = {1, 2};
	std::vector<float> vec = {2, 3};
	
	std::cout << "Print array:\n";
	print_array(arr, std::size(arr));
	
	std::cout << '\n';
	
	std::cout << "Print vector:\n";
	print_array(vec.data(), vec.size()); // std::size(vec) works too
}
Print array:
1
2

Print vector:
2
3
What about passing a pointer to the array? it's very clean writing, you still need to pass the length as a second parameter, but it's quite effective. Using std::size can improve reliability, as stated above.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

void Foo(int* i_array, int i_len)
{
	for (int i = 0; i < i_len; i++)
		cout << i_array[i] << endl;
}


int main()
{
	int MyArray[5];
	MyArray[0] = 100;
	MyArray[1] = 200;
	MyArray[2] = 300;
	MyArray[3] = 400;
	MyArray[4] = 500;
	Foo(MyArray, 5);
}

Indeed. The vector is fine with OpenGL.


you can declare an array without specifying the size,
int arr[] = {1, 2};

Note, technically you do specify the exact size in that statement, even though you don't write a verbatim number. The size is implicit in the initializer; easy for compiler to count and use.


Note 2: There is no array in:
void foo( float arr[] );
The above declaration is an alias syntax for:
void foo( float* arr );
The rationale is that you don't want to make a copy of an array. The language does not support that anyway.

The std::vector does know how to copy itself. Passing by reference avoids that performance penalty.

OpenGL, it does not take vectors as paremeters, it wants arrays

Now it should be obvious that OpenGL does not take "arrays"; it takes pointers and I bet that it takes the "size" (might be called "element count") as an additional parameter.


Note 3: Even if one has an array by reference parameter:
void foo( float (&arr)[18] );
then one still does not "pass the size" into the function. The function has its "hardsized array" (reference) no matter what the callers have. The side-effect is that such function cannot be called with arbitrary array.
Topic archived. No new replies allowed.