I declare the following array:
char* array [2] = { "One", "Two"};
I pass this array to a function. How can I find the length of this array in the function?
You can't find the length of an array after you pass it to a function without extra effort. You'll need to:
Use a container that stores the size, such as vector (recommended).
Pass the size along with it. This will probably require the least modification to your existing code and be the quickest fix.
Use a sentinel value, like C strings do1. This makes finding the length of the array a linear time operation and if you forget the sentinel value your program will likely crash. This is the worst way to do it for most situations.
Use templating to deduct the size of the array as you pass it. You can read about it here: How does this Array Size Template Work?
1 In case you were wondering, most people regret the fact that C strings work this way.
When you pass an array there is NOT an easy way to determine the size within the function.
You can either pass the array size as a parameter
or
use std::vector<std::string>
If you are feeling particularly adventurous you can use some advanced template techniques
In a nutshell it looks something like
template <typename T, size_t N>
void YourFunction( T (&array)[N] )
{
size_t myarraysize = N;
}
C is doing some trickery behind your back.
void foo(int array[]) {
/* ... */
}
void bar(int *array) {
/* ... */
}
Both of these are identical:
6.3.2.1.3: Except when it is the operand of the sizeof operator or the unary & operator,
or is a string literal used to initialize an array, an expression that has type
‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’
that points to the initial element of the array object and is not an lvalue. If
the array object has register storage class, the behavior is undefined.
As a result, you don't know, inside foo() or bar(), if you were
called with an array, a portion of an array, or a pointer to a single
integer:
int a[10];
int b[10];
int c;
foo(a);
foo(&b[1]);
foo(&c);
Some people like to write their functions like: void foo(int *array)
just to remind themselves that they weren't really passed an array,
but rather a pointer to an integer and there may or may not be more
integers elsewhere nearby. Some people like to write their functions
like: void foo(int array[]), to better remind themselves of what the
function expects to be passed to it.
Regardless of which way you like to do it, if you want to know how long
your array is, you've got a few options:
Pass along a length paramenter too. (Think int main(int argc, char
*argv)).
Design your array so every element is non-NULL, except the last
element. (Think char *s="almost a string"; or execve(2).)
Design your function so it takes some other descriptor of the
arguments. (Think printf("%s%i", "hello", 10); -- the string describes
the other arguments. printf(3) uses stdarg(3) argument handling, but
it could just as easily be an array.)
Getting the array-size from the pointer isn't possible. You could just terminate the array with a NULL-pointer. That way your function can search for the NULL-pointer to know the size, or simply just stop processing input once it hits the NULL...
If you mean how long are all the strings added togather.
int n=2;
int size=0;
char* array [n] = { "One", "Two"};
for (int i=0;i<n;++i)
size += strlen(array[i];
Added:
yes thats what im currently doing but i wanted to remove that extra
paramater. oh well –
Probably going to get a bad response for this, but you could always use the first pointer to store the size, as long as you don't deference it or mistake it for actually being a pointer.
char* array [] = { (char*)2,"One", "Two"};
long size=(long)array[0];
for(int i=1; i<= size;++i)
printf("%s",array[i]);
Or you could NULL terminate your array
char* array [] = { "One", "Two", (char*)0 };
for(int i=0;array[i]!=0;++i)
{
printf("%s",array[i]);
}
Use the new C++11 std::array
http://www.cplusplus.com/reference/stl/array/
the standard array has the size method your looking for
Related
Given to functions void main() and void hello(byte* a[4]). Main function has an array of four bytes. The array's reference needs to be passed to the function hello for manipulation. I would expect the right syntax to be:
void hello(byte* a[4]){
// Manipulate array
a[0] = a[0]+1;
}
void main(){
byte stuff[4] = {0,0,0,0};
hello(&stuff);
// hopefully stuff is now equal {1,0,0,0}
}
Alternatively I see others using this form of decaration:
void hello(byte (&a)[4])
Is this the right way to do it?
There are many different options here depending on what you want to do here.
If you have a raw array of byte objects, you can pass it into a function like this:
void hello(byte arr[]) {
// Do something with arr
}
int main() {
byte arr[4];
hello(arr);
}
The mechanism by which the array is passed into the function (a pointer to the first element of the array is passed to the function) functions similarly to pass-by-reference: any changes you make to arr in hello will stick in main even though you didn't explicitly pass in a reference to it. However, the hello function won't check whether the array has size four or not - it'll take in as input an array of any number of bytes.
You can also write
void hello(byte (&arr)[4]) {
// ...
}
int main() {
byte arr[4];
hello(arr);
}
The syntax byte (&arr)[4] means "a reference to an array of four bytes." This explicitly passes the array by reference into hello, and it will check the size of the array to make sure it's correct. However, this is very unusual syntax and rarely seen in practice.
But perhaps the best idea is to not use raw arrays and to use std::array instead:
void hello(std::array<byte, 4>& arr) {
// Do something with arr
}
int main() {
std::array<byte, 4> arr;
hello(arr);
}
Now, there's no weirdnesses about strange parentheses in the syntax for arrays of bytes and there's no worries about size checking. Everything is handled properly because std::array is an object type that has all the advantages of regular object types. I'd recommend going with this last approach above all the other ones.
Arrays are already passed by pointer.
So this:
int a(int array[]) {
}
Is the same as doing this:
int a(int * array) {
}
Doing this:
void hello(byte (&a)[4])
only allows arrays with a length of 4 to be passed in.
byte* a[4] is an array of four pointers to byte, except in a parameter list.
In a parameter list, it is a pointer to a pointer to a byte – i.e. it is equivalent to byte**.
byte (*a)[4] is a pointer to a four-element array.
byte (&a)[4] is a reference to a four-element array.
In your case, &stuff is a pointer to a four-element array, so your parameter should be byte (*a)[4].
I have read this answer
Adressing your question - pointer to array is usefull to pass an
entire array of compile-time known size and preserve information about
its size during argument passing.
But i don't really understand it. Aren't the size of arrays with a given size already known at compile-time? How do you get the size of the array if you have a pointer to it? Take this example:
void func(int (*array)[5])
{
}
// identical to
void func(int *array, int size)
{
}
You have to put 5 there, so what's the point of it? You still can't iterate over it unless you already know the size.
Aren't the size of arrays with a given size already known at compile-time?
Yes, they are.
How do you get the size of the array if you have a pointer to it?
You don't.
You have to put 5 there, so what's the point of it?
It prevents mistakes. You can only pass an array of the correct size to this function; the compiler will reject it if you try to pass a pointer, or wrongly sized array.
You still can't iterate over it unless you already know the size.
You can get the size from the array type:
size_t size = sizeof(*array) / sizeof(**array); // old school
size_t size = std::extent<decltype(*array)>::value; // C++11 or later
size_t size = std::size(*array); // the future, maybe
Or you could make the function a template, usable for any array size:
template <size_t N>
void func(int (&array)[N])
{
for (int i : array) // size is known
std::cout << i << '\n';
}
(I also changed the type to a reference rather than a pointer, to make the syntax clearer. It's possible that the answer you quote was for C, not for C++, in which case there are no references or templates.)
Adressing your question - pointer to array is useful to pass an
entire array of compile-time known size and preserve information
about its size during argument passing.
This is just true for char arrays as you don't need to pass size of array explicitly since its deduced by the null terminator.
When it comes to integer arrays (OR arrays where there is no terminator), I would say that they are not self-contained as passing pointer to array won't let that function to deduce the size of array. You have to pass size explicitly.
Mike Seymour's answer with the template example has made it click to me that you can use sizeof operator here.
void func(int (*array)[5])
{
std::size_t n = sizeof(*array) / sizeof(**array);
std::cout << n;
}
int main()
{
int array[5] = { 1, 2, 3, 4, 5 };
func(&array);
}
This approach works best in C, where you don't have templates.
if you have a pointer p point to the array
and you want to get the array size.
try size_t array_size = *(size_t*)p;
Dangerous. But it works.
Is there any way to print length of an array which contains an element 0 and that array has been passed to a function which can have only one argument as the array?
Example:
int arrLen(int arr[])
{
//get size here;
}
int main()
{
int arr[]={0,1,2,3,4,5};
arrLen(arr);
}
There is a limitation in C++ that we can not compare the elements of an array with a NULL if it has a zero, but still asking if there is a way to do that. I can only pass array to function is my limitation.
In your very example, you can use function template to get what you want:
template <size_t N>
int arrLen(int (&arr)[N])
{
return N;
}
The only answer is that you can't get the size of the array once it's been passed as an argument. You have to remember that when passing an array as an argument, it decays to a pointer, and the compiler have no idea of what the pointer actually points to. You should also remember that sizeof is a compile-time operation, the result of a sizeof operation is done by the compiler, and not at runtime.
You either have to put a special end-of-array marker, like strings use the '\0' character to mark the end of a string, at the end of the array (note that this end-of-array marker can be anything that's not supposed to be in the array, be it a zero, -1 or something else). Or you have to pass the length as an argument to the function.
In C when pass an array as an argument to a function, you're passing a pointer to the first element. If you want to pass the size of the array, you should pass it as a separated argument.
You can store the length of the array in the first element of it:
int arr[] = {-1,0,1,2,3,4,5};
arr[0] = sizeof(arr) / sizeof(arr[0]) - 1;
After you do this, you'll get the array's size in arr[0].
There's two ways to achieve what you want:
Know the size of the array - you have to either hard-code it in the function, or pass it as parameter.
Use a sentinel value. When you find the sentinel value, you know you've reached the end of the data. For example, C strings work using \0 as a sentinel.
The latter one seems to be applicable here (e.g. using INT_MIN as sentinel), but unless you have very good reasons, don't do it. Simply pass the length.
Since you control the function that computes the array length, you could decide that a specific int value (or even sequence) such as -1 marks the end of your array. You can then implement your arrLen function like this (with additional improvements for e.g. int overflow):
int arrLen(int arr[])
{
int size = 0;
int* p = arr;
while (*p != -1) {
++size;
++p;
}
return size;
}
then, of course, you need to properly "close" your array on the calling site, or you'll run into trouble:
int arr[]={0,1,2,3,4,5, -1 };
Thanks for the help, but that is my limitation to pass only 1 argument into the function and that can only be an array.
anyways I just wrote that main function to make an understanding, but actually that main function is not available to me. So finally I end up with a function which can get an argument that can be an int array and return the size of array.
I tried with something that to convert my int array into an ascii array of those int values and since a NULL or '\0' can never be equal to a '0', so comparing them with NULL up to the end of an array is possible.
But again I got stuck when I'm going to convert the array, I required the length.
I am confused about which syntax to use if I want to pass an array of known or unknown size as a function parameter.
Suppose I have these variants for the purpose:
void func1(char* str) {
//print str
}
void func2(char str[]) {
//print str
}
void func3(char str[10]) {
//print str
}
What are the pros and cons of using each one of these?
All these variants are the same. C just lets you use alternative spellings but even the last variant explicitly annotated with an array size decays to a normal pointer.
That is, even with the last implementation you could call the function with an array of any size:
void func3(char str[10]) { }
func("test"); // Works.
func("let's try something longer"); // Not a single f*ck given.
Needless to say this should not be used: it might give the user a false sense of security (“oh, this function only accepts an array of length 10 so I don’t need to check the length myself”).
As Henrik said, the correct way in C++ is to use std::string, std::string& or std::string const& (depending on whether you need to modify the object, and whether you want to copy).
Note that in C++, if the length of the array is known at compile time (for example if you passed a string literal), you can actually get its size:
template<unsigned int N>
void func(const char(&str)[N])
{
// Whatever...
}
int main()
{
func("test"); // Works, N is 5
}
In C++, use void func4(const std::string& str).
These are all functionally identical. When you pass an array to a function in C, the array gets implicitly converted to a pointer to the first element of the array. Hence, these three functions will print the same output (that is, the size of a pointer to char).
void func1(char* str) {
printf("sizeof str: %zu\n", sizeof str);
}
void func2(char str[]) {
printf("sizeof str: %zu\n", sizeof str);
}
void func3(char str[10]) {
printf("sizeof str: %zu\n", sizeof str);
}
This conversion only applies to the first dimension of an array. A char[42][13] gets converted to a char (*)[13], not a char **.
void func4(char (*str_array)[13]) {
printf("sizeof str_array: %zu\n"
"sizeof str_array[0]: %zu\n", sizeof str_array, sizeof str_array[0]);
}
char (*)[13] is the type of str_array. It's how you write "a pointer to an array of 13 chars". This could have also been written as void func4(char str_array[42][13]) { ... }, though the 42 is functionally meaningless as you can see by experimenting, passing arrays of different sizes into func4.
In C99 and C11 (but not C89 or C++), you can pass a pointer to an array of varying size into a function, by passing it's size along with it, and including the size identifier in the [square brackets]. For example:
void func5(size_t size, char (*str_array)[size]) {
printf("sizeof str_array: %zu\n"
"sizeof str_array[0]: %zu\n", sizeof str_array, sizeof str_array[0]);
}
This declares a pointer to an array of size chars. Note that you must dereference the pointer before you can access the array. In the example above, sizeof str_array[0] evaluates to the size of the array, not the size of the first element. As an example, to access the 11th element, use (*str_array)[11] or str_array[0][11].
In C, the first two definitions are equivalent.The third one is essentially same but it gives an idea about the size of the array.
If printing str is your intent, then you can safely use any of them.Essentially all three of the functions are passed a parameter of type char*,just what printf() needs to print a string.And lest you don't know, despite what it may seem, all parameter passing in C is done in pass-by-value mode.
Edit: Seems like I'll have to be very rigorous in my choice of words on SO henceforth.Well,in the third case it gives no idea about the size of the array to the function to which it is passed as eventually it is reduced to type char* just as in the first two cases.I meant to say it kinda tells the human reading it that the array's size is 10.Also,it is not wrong/illegal in C.But for the program,doing it is as good as useless.It gives no idea whatsoever about the array size to the function it is passed to.Mr.Downvoter, thanks for pointing out that casual attitude and negligence is not tolerated on SO.
In a one dimensional array they are all treated the same by the compiler. However for a two or more dimensional array, (e.g. myArray[10][10]), it is useful as it can be used to determine the row/column length of an array.
To add-on, describing in points.
1) As everyone told it is same.
2) Arrays are decayed into pointers when they are passed in the function arguments.
3) Fundamental problem could be finding the size of a array in the function. For that we can use macro like.
#define noOfElements(v) sizeof(v)/sizeof(0[v])
int arr[100]
myfunction ( arr, noOfElements(arr))
either 0[v] or v[0] can be used in the macro, where the first is used to avoid user defined data type passed in to noOfElements.
Hope this helps.
As i want to find array size dynamically in function, i used sizeof operator. But i got some unexpected result.
here is one demo program to show you, what i want to do.
//------------------------------------------------------------------------------------------
#include <iostream>
void getSize(int *S1){
int S_size = sizeof S1/sizeof(int);
std::cout<<"array size(in function):"<<S_size<<std::endl;
}
int main(){
int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
getSize(S);
std::cout<<"array size:"<<sizeof S/sizeof(int)<<std::endl;
return 0;
}
//------------------------------------------------------------------------------------------
compilation command : g++ demo1.cc -o demo1 {fedora 12}
output:
array size(in function):2
array size:19
please explain ,why this is happening.
what can be done to solve this problem.
void getSize(int *S1)
When you pass an array to this function, it decays to pointer type, so sizeof operator will return the size of pointer.
However, you define your function as,
template<int N>
void getSize(int (&S1)[N])
{
//N is the size of array
int S_size1 = N;
int S_size2 = sizeof(S1)/sizeof(int); //would be equal to N!!
std::cout<<"array size(in function):"<<S_size1<<std::endl;
std::cout<<"array size(in function):"<<S_size2<<std::endl;
}
int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
getSize(S); //same as before
then you can have the size of array, in the function!
See the demonstration yourself here : http://www.ideone.com/iGXNU
Inside getSize(), you're getting size of pointer, which is 8 bytes (since you're probably running 64-bit OS). In main(), you're getting size of array.
If you want to know array size, pass result of sizeof(S) as additional argument to getSize().
More alternatives would be using some container (like std::vector) or turning function into template function, as Nawaz proposed.
S is an int *, a pointer to an integer, which is a memory address, which is on your machine twice the size of an integer.
If you want the size of the array (I.e., the number of elements), you can't get that directly in pure C. But since this is a c++ question, there is a way: use a vector, which has a size() method.
Actually, this isn't quite true: within the function that you declare S (and only if it's explicitly initialized at compile time as you do in your example -- even new int[19] doesn't work), the sizeof operator actually does get the correct answer, which is why c++ allows you to do this:
int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
vector<int> v(S, S + sizeof(S) / sizeof(int) );
and then you can use v.size() (see these docs).
The template version by Nawaz elsewhere is another excellent suggestion which forces the compiler into carrying the full information about the construction of the c++ array around (again, note that this is all known at compile time, which is why you can be explicit about the size in the argument).
you are getting the size of the pointer to the array. If you want the size of the array you have to multiply the number of elements by the size of each element.
You will have to pass the size of the array to the function.
Since you are only passing a pointer to the first element in the array, your function has no information on its actual size.
void getSize(int *S1, size_t size)
{
int S_Size = sizeof(*S1) * size;
}
This is redundant though, if you think about it :D
To prevent this type of accidental misuse of sizeof, you can define a function which only works on arrays:
template<class T, int N>
int array_size(T (&)[N]) {
return N;
}
If you use this in your code, you'll see a compiler error when applied to S1, as it is not an array. Plus, it's shorter and a bit more explicit than sizeof array / sizeof array[0] (using the size of the first item means you don't have to repeat the array type).
This also already exists in Boost in a more general form (accepting anything with a size method, such as std::vector).