Sign in to follow this  
thecoast47

Passing Array into function C++ issue

Recommended Posts

Yeah so i'm currently learning c++. Coming from programming in Java I was always used to getting the length of arrays by just putting ".length" but in C++ a little math is required. So basically what i tried to do is make a function that takes the array and returns the length. Sounds simple right? The problem is that i need the size of the whole array and the size of the data type in order to calculate the length of the array but apparently the size of the array changes when you pass it into a function.
Is there a way around this or am i screwed?
[code]

# include <iostream>

using std:: cout;
using std:: cin;
using std:: endl;

int main(){
//Adding prototype
int GetLength(int array[]);
//Initilizing Variables
int array[80];
int pause = 0;
int size =0 ;
int sizeFunc = 0;

size = (sizeof(array)/sizeof(int)) -1 ;

for (int i = 0; i < size ; i++){
array[i] = i +1 ;
}
sizeFunc = GetLength(array);
//Sets Numbers
cout << "Size Function Returns..." << sizeFunc << endl;
cout << "Regular Calculation..." << size;
cin >> pause;
return 0;
}
int GetLength( int Array[]){
int size =0 ;
cout << "Array size that passed into function is--->" << sizeof(Array) << endl;
cout << "Array size type that passed into function is--->" << sizeof(int) << endl << endl;
size = (sizeof(Array)/sizeof(int)) - 1 ;
return size ;
}
[/code]

i feel like such a noob for asking this...
the humiliation...

Share this post


Link to post
Share on other sites
The size of the array hasn't changed at all. What you've encountered is colloquially known as array to pointer decay. In essence your array parameter has been converted to a pointer type.

There are a few things you "could" do to get the size of the array, assuming it's static at compile time, such as through the use of templates.

Realistically though, the use of std::vector is recommended, allocating fixed size arrays on the stack is generally A Bad Idea (tm).

Share this post


Link to post
Share on other sites
[quote name='karwosts' timestamp='1297925907' post='4775286']
Why not a std::vector? That's why it's there is to save you these kinds of headaches.
[/quote]

I haven't made it that far into my book yet but if you say using std::vector will work then i'll take your word for it.


Share this post


Link to post
Share on other sites
If you aren't that far along, and wish to still use arrays, then the answer is as follows: You pass the size in to every function that must access your array.

Share this post


Link to post
Share on other sites
For completeness, here is a function that returns the static size of an array. It will not work with an array passed to a function, but it will not compile for you in that case.

This is reasonably advanced code, if you haven't come across std::vector<> yet you might not understand how it works. Basically, it takes advantage of the fact that C++ arrays include their size as part of the type, and uses C++ templates to deduce the size of the array passed to it.

[code]
template<typename T, size_t N>
size_t array_size(T (&)[N])
{
return N;
}
[/code]
As the others have mentioned, using raw arrays isn't recommended. They can be good for certain kinds of static data that cannot be externalised into a file.

Coming from a Java background, std::vector<> is similar to ArrayList<>.

Share this post


Link to post
Share on other sites
[quote name='rip-off' timestamp='1297934202' post='4775339']
For completeness, here is a function that returns the static size of an array. It will not work with an array passed to a function, but it will not compile for you in that case.

This is reasonably advanced code, if you haven't come across std::vector<> yet you might not understand how it works. Basically, it takes advantage of the fact that C++ arrays include their size as part of the type, and uses C++ templates to deduce the size of the array passed to it.

[code]
template<typename T, size_t N>
size_t array_size(T (&)[N])
{
return N;
}
[/code]
As the others have mentioned, using raw arrays isn't recommended. They can be good for certain kinds of static data that cannot be externalised into a file.

Coming from a Java background, std::vector<> is similar to ArrayList<>.
[/quote]
Since we're going there... Let's not forget the static compile time determination:
[code]template<class T>
struct array_size;

template<class T, size_t S>
struct array_size<T[S]> { static const int size = S; };
//or std::extent if in C++0x
[/code]

Share this post


Link to post
Share on other sites
What is the utility of that? If you can only pass types to it, and not values, then how does it help? It would appear to me that writing array_size<char[400]>::size is a verbose way to write "400". The only place I can see that as being useful is when the array is a typedef. An optimising compiler will happily inline the function I provided and should generate a constant at the calling location, so you should get compile time determination of the array length too.

Unless it has some extra secret sauce I'm not aware of? Or am I missing something in my understanding?

Share this post


Link to post
Share on other sites
[quote name='rip-off' timestamp='1297942291' post='4775361']
What is the utility of that? If you can only pass types to it, and not values, then how does it help? It would appear to me that writing array_size<char[400]>::size is a verbose way to write "400". The only place I can see that as being useful is when the array is a typedef. An optimising compiler will happily inline the function I provided and should generate a constant at the calling location, so you should get compile time determination of the array length too.

Unless it has some extra secret sauce I'm not aware of? Or am I missing something in my understanding?
[/quote]

A compile time unrolled loop comes to mind.

Share this post


Link to post
Share on other sites
Why not just use a Boost Array? That's the closest equivalent to a Java array.

It has all the type safety and container functions without the overhead of a vector.

Share this post


Link to post
Share on other sites
[quote name='Storyyeller' timestamp='1298007531' post='4775718']
Why not just use a Boost Array? That's the closest equivalent to a Java array.

It has all the type safety and container functions without the overhead of a vector.
[/quote]

1. This is For Beginners, as such boost is generally a no-no. Heck, even our template skulldrudgery up above shouldn't be here.

2. "overhead of a vector" is a misnomer. It has the same amount of overhead as an array. One would use boost array instead of a vector in the case when one has a statically sized array but would like the advantage of a uniform interface (begin(), end(), etc.) for access to the array.

Share this post


Link to post
Share on other sites
Just pass the size of the array into the function like Washu said until you start using std::vector and then you can use size()
[code]
void modifyArray(int array[],int size)
{
for (int i=0;i<size;++i)
{
//do something useful with array
}
}
[/code]

Templates look funky until you have a good understanding of them.

Share this post


Link to post
Share on other sites
Just a reminder, [b]sizeof()[/b] [i]is not a function[/i]. It is a compile-time operator. If you can't substitute a constant value for [b]sizeof(something)[/b] and expect your code to work reliably, then you've used it incorrectly.

Share this post


Link to post
Share on other sites
In any case, most up to date compilers now offer std::array in the <array> header, as it's at C++0x feature. Slightly less up to date compilers have the equivalent std::tr1::array from TR1.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this