Why isn't the size of an array sent as a parameter the same as within main?
#include <stdio.h>
void PrintSize(int p_someArray[10]);
int main () {
int myArray[10];
printf("%d\n", sizeof(myArray)); /* As expected, 40 */
PrintSize(myArray);/* Prints 4, not 40 */
}
void PrintSize(int p_someArray[10]){
printf("%d\n", sizeof(p_someArray));
}
An array-type is implicitly converted into pointer type when you pass it in to a function.
So,
void PrintSize(int p_someArray[10]) {
printf("%zu\n", sizeof(p_someArray));
}
and
void PrintSize(int *p_someArray) {
printf("%zu\n", sizeof(p_someArray));
}
are equivalent. So what you get is the value of sizeof(int*)
It's a pointer, that's why it's a common implementation to pass the size of the array as a second parameter to the function
As others have stated, arrays decay to pointers to their first element when used as function parameters. It's also worth noting that sizeof does not evaluate the expression and does not require parentheses when used with an expression, so your parameter isn't actually being used at all, so you may as well write the sizeof with the type rather than the value.
#include <stdio.h>
void PrintSize1 ( int someArray[][10] );
void PrintSize2 ( int someArray[10] );
int main ()
{
int myArray[10];
printf ( "%d\n", sizeof myArray ); /* as expected 40 */
printf ( "%d\n", sizeof ( int[10] ) ); /* requires parens */
PrintSize1 ( 0 ); /* prints 40, does not evaluate 0[0] */
PrintSize2 ( 0 ); /* prints 40, someArray unused */
}
void PrintSize1 ( int someArray[][10] )
{
printf ( "%d\n", sizeof someArray[0] );
}
void PrintSize2 ( int someArray[10] )
{
printf ( "%d\n", sizeof ( int[10] ) );
}
So, you will need to pass the lenght of the array as a second parameter. When you are writing code, in which you both declare an array of constant size, and later pass that array to a function, it is a pain to have the array-length constant show up several places in your code...
K&R to the rescue:
#define N_ELEMENTS(array) (sizeof(array)/sizeof((array)[0]))
So now you can do e.g:
int a[10];
...
myfunction(a, N_ELEMENTS(a));
The behavior you found is actually a big wart in the C language. Whenever you declare a function that takes an array parameter, the compiler ignores you and changes the parameter to a pointer. So these declarations all behave like the first one:
void func(int *a)
void func(int a[])
void func(int a
typedef int array_plz[5];
void func(array_plz a)
a will be a pointer to int in all four cases. If you pass an array to func, it will immediately decay into a pointer to its first element. (On a 64-bit system, a 64-bit pointer is twice as large as a 32-bit int, so your sizeof ratio returns 2.)
The only purpose of this rule is to maintain backwards compatibility with historical compilers that did not support passing aggregate values as function arguments.
This does not mean that it’s impossible to pass an array to a function. You can get around this wart by embedding the array into a struct (this is basically the purpose of C++11’s std::array):
struct array_rly {
int a[5];
};
void func(struct array_rly a)
{
printf("%zd\n", sizeof(a.a)/sizeof(a.a[0])); /* prints 5 */
}
or by passing a pointer to the array:
void func(const int (*a)[5])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0])); /* prints 5 */
}
In case the array size isn’t a compile-time constant, you can use the pointer-to-array technique with C99 variable-length arrays:
void func(int n, const int (*a)[n])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0])); /* prints n */
}
Because arrays decay into pointers when they are passed as parameters. This is how C works, although you can pass "arrays" in C++ by reference and overcome this issue. Note that you can pass arrays of different sizes to this function:
// 10 is superfluous here! You can pass an array of different size!
void PrintSize(int p_someArray[10]);
In c++ you can pass an array by reference for this very purpose :
void foo(int (&array)[10])
{
std::cout << sizeof(array) << "\n";
}
In the C language, there is no method to determine the
size of an unknown array, so the quantity needs to
be passed as well as a pointer to the first element.
You can't pass arrays to functions.
If you really wanted to print the size, you could pass a pointer to an array, but it won't be generic at all as you need to define the array size for the function as well.
#include <stdio.h>
void PrintSize(int (*p_anArray)[10]);
int main(void) {
int myArray[10];
printf("%d\n", sizeof(myArray)); /* as expected 40 */
PrintSize(&myArray);/* prints 40 */
}
void PrintSize(int (*p_anArray)[10]){
printf("%d\n", (int) sizeof(*p_anArray));
}
The behavior is by design.
Same syntax in function parameter declaration means completely different thing than in local variable definition.
The reason is described in other answers.
In C language when you pass the array as an argument to the function , it is automatically converted into pointer ,array passing from one function other function is know as call by reference . That is the reason the called function only receives the pointer which point to the first element of function This is the reason
fun(int a[]) is similar to fun(int *a) ;
so when you print the size of array it will print the size of first element.
In 'C' programming languange 'sizeof()' is the operator and he returns the size of the object in bytes.Argument of the 'sizeof()' operator must be a left-value type(integer,float number,struct,array).So if you want to know the size of an array in bytes you can do it very simple.Just use the 'sizeof()' operator and for his argument use the array name.For example:
#include <stdio.h>
main(){
int n[10];
printf("Size of n is: %d \n", sizeof(n));
}
Output on 32 bit system will be: Size of n is: 40.Because ineteger on 32 system is 4bytes.On 64x it is 8bytes.In this case we have 10 integers declared in one array.So the result is '10 * sizeof(int)'.
Some tips:
If we have an array declared like this one 'int n[]={1, 2, 3, ...155..};'.
So we want to know how many elements are stored in this array.
Use this alghorithm:
sizeof(name_of_the_array) / sizeof(array_type)
Code: #include
main(){
int n[] = { 1, 2, 3, 44, 6, 7 };
printf("Number of elements: %d \n", sizeof(n) / sizeof(int));
return 0;
}
Arrays are only loosely sized. For the most part, an array is a pointer to memory. The size in your declaration only tells the compiler how much memory to allocate for the array - it's not associated with the type, so sizeof() has nothing to go on.
Related
Why isn't the size of an array sent as a parameter the same as within main?
#include <stdio.h>
void PrintSize(int p_someArray[10]);
int main () {
int myArray[10];
printf("%d\n", sizeof(myArray)); /* As expected, 40 */
PrintSize(myArray);/* Prints 4, not 40 */
}
void PrintSize(int p_someArray[10]){
printf("%d\n", sizeof(p_someArray));
}
An array-type is implicitly converted into pointer type when you pass it in to a function.
So,
void PrintSize(int p_someArray[10]) {
printf("%zu\n", sizeof(p_someArray));
}
and
void PrintSize(int *p_someArray) {
printf("%zu\n", sizeof(p_someArray));
}
are equivalent. So what you get is the value of sizeof(int*)
It's a pointer, that's why it's a common implementation to pass the size of the array as a second parameter to the function
As others have stated, arrays decay to pointers to their first element when used as function parameters. It's also worth noting that sizeof does not evaluate the expression and does not require parentheses when used with an expression, so your parameter isn't actually being used at all, so you may as well write the sizeof with the type rather than the value.
#include <stdio.h>
void PrintSize1 ( int someArray[][10] );
void PrintSize2 ( int someArray[10] );
int main ()
{
int myArray[10];
printf ( "%d\n", sizeof myArray ); /* as expected 40 */
printf ( "%d\n", sizeof ( int[10] ) ); /* requires parens */
PrintSize1 ( 0 ); /* prints 40, does not evaluate 0[0] */
PrintSize2 ( 0 ); /* prints 40, someArray unused */
}
void PrintSize1 ( int someArray[][10] )
{
printf ( "%d\n", sizeof someArray[0] );
}
void PrintSize2 ( int someArray[10] )
{
printf ( "%d\n", sizeof ( int[10] ) );
}
So, you will need to pass the lenght of the array as a second parameter. When you are writing code, in which you both declare an array of constant size, and later pass that array to a function, it is a pain to have the array-length constant show up several places in your code...
K&R to the rescue:
#define N_ELEMENTS(array) (sizeof(array)/sizeof((array)[0]))
So now you can do e.g:
int a[10];
...
myfunction(a, N_ELEMENTS(a));
The behavior you found is actually a big wart in the C language. Whenever you declare a function that takes an array parameter, the compiler ignores you and changes the parameter to a pointer. So these declarations all behave like the first one:
void func(int *a)
void func(int a[])
void func(int a
typedef int array_plz[5];
void func(array_plz a)
a will be a pointer to int in all four cases. If you pass an array to func, it will immediately decay into a pointer to its first element. (On a 64-bit system, a 64-bit pointer is twice as large as a 32-bit int, so your sizeof ratio returns 2.)
The only purpose of this rule is to maintain backwards compatibility with historical compilers that did not support passing aggregate values as function arguments.
This does not mean that it’s impossible to pass an array to a function. You can get around this wart by embedding the array into a struct (this is basically the purpose of C++11’s std::array):
struct array_rly {
int a[5];
};
void func(struct array_rly a)
{
printf("%zd\n", sizeof(a.a)/sizeof(a.a[0])); /* prints 5 */
}
or by passing a pointer to the array:
void func(const int (*a)[5])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0])); /* prints 5 */
}
In case the array size isn’t a compile-time constant, you can use the pointer-to-array technique with C99 variable-length arrays:
void func(int n, const int (*a)[n])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0])); /* prints n */
}
Because arrays decay into pointers when they are passed as parameters. This is how C works, although you can pass "arrays" in C++ by reference and overcome this issue. Note that you can pass arrays of different sizes to this function:
// 10 is superfluous here! You can pass an array of different size!
void PrintSize(int p_someArray[10]);
In c++ you can pass an array by reference for this very purpose :
void foo(int (&array)[10])
{
std::cout << sizeof(array) << "\n";
}
In the C language, there is no method to determine the
size of an unknown array, so the quantity needs to
be passed as well as a pointer to the first element.
You can't pass arrays to functions.
If you really wanted to print the size, you could pass a pointer to an array, but it won't be generic at all as you need to define the array size for the function as well.
#include <stdio.h>
void PrintSize(int (*p_anArray)[10]);
int main(void) {
int myArray[10];
printf("%d\n", sizeof(myArray)); /* as expected 40 */
PrintSize(&myArray);/* prints 40 */
}
void PrintSize(int (*p_anArray)[10]){
printf("%d\n", (int) sizeof(*p_anArray));
}
The behavior is by design.
Same syntax in function parameter declaration means completely different thing than in local variable definition.
The reason is described in other answers.
In C language when you pass the array as an argument to the function , it is automatically converted into pointer ,array passing from one function other function is know as call by reference . That is the reason the called function only receives the pointer which point to the first element of function This is the reason
fun(int a[]) is similar to fun(int *a) ;
so when you print the size of array it will print the size of first element.
In 'C' programming languange 'sizeof()' is the operator and he returns the size of the object in bytes.Argument of the 'sizeof()' operator must be a left-value type(integer,float number,struct,array).So if you want to know the size of an array in bytes you can do it very simple.Just use the 'sizeof()' operator and for his argument use the array name.For example:
#include <stdio.h>
main(){
int n[10];
printf("Size of n is: %d \n", sizeof(n));
}
Output on 32 bit system will be: Size of n is: 40.Because ineteger on 32 system is 4bytes.On 64x it is 8bytes.In this case we have 10 integers declared in one array.So the result is '10 * sizeof(int)'.
Some tips:
If we have an array declared like this one 'int n[]={1, 2, 3, ...155..};'.
So we want to know how many elements are stored in this array.
Use this alghorithm:
sizeof(name_of_the_array) / sizeof(array_type)
Code: #include
main(){
int n[] = { 1, 2, 3, 44, 6, 7 };
printf("Number of elements: %d \n", sizeof(n) / sizeof(int));
return 0;
}
Arrays are only loosely sized. For the most part, an array is a pointer to memory. The size in your declaration only tells the compiler how much memory to allocate for the array - it's not associated with the type, so sizeof() has nothing to go on.
Is it possible to determine the size of an array if it was passed to another function (size isn't passed)? The array is initialized like int array[] = { XXX } ..
I understand that it's not possible to do sizeof since it will return the size of the pointer .. Reason I ask is because I need to run a for loop inside the other function where the array is passed. I tried something like:
for( int i = 0; array[i] != NULL; i++) {
........
}
But I noticed that at the near end of the array, array[i] sometimes contain garbage values like 758433 which is not a value specified in the initialization of the array..
The other answers overlook one feature of c++. You can pass arrays by reference, and use templates:
template <typename T, int N>
void func(T (&a) [N]) {
for (int i = 0; i < N; ++i) a[i] = T(); // reset all elements
}
then you can do this:
int x[10];
func(x);
but note, this only works for arrays, not pointers.
However, as other answers have noted, using std::vector is a better choice.
If it's within your control, use a STL container such as a vector or deque instead of an array.
Nope, it's not possible.
One workaround: place a special value at the last value of the array so you can recognize it.
One obvious solution is to use STL. If it's not a possibility, it's better to pass array length explicitly.
I'm skeptical about use the sentinel value trick, for this particular case. It works
better with arrays of pointers, because NULL is a good value for a sentinel. With
array of integers, it's not that easy - you need to have
a "magic" sentinel value, which is
not good.
Side note: If your array is defined and initalized as
int array[] = { X, Y, Z };
in the same scope as your loop, then
sizeof(array) will return it's real size in bytes, not the size of the pointer. You can get the array length as
sizeof(array) / sizeof(array[0])
However, in general case, if you get array as a pointer, you can't use this trick.
You could add a terminator to your int array then step through the array manually to discover the size within the method.
#include<iostream>
using namespace std;
int howBigIsBareArray(int arr[]){
int counter = 0;
while (arr[counter] != NULL){
counter++;
}
return counter;
}
int main(){
int a1[6] = {1,2,3,4,5,'\0'};
cout << "SizeOfMyArray: " << howBigIsBareArray(a1);
}
This program prints:
SizeOfMyArray: 5
This is an O(n) time complexity operation which is bad. You should never be stepping through an array just to discover its size.
If you can't pass the size, you do need a distinguishable sentinel value at the end (and you need to put it there yourself -- as you've found, you can't trust C++ to do it automagically for you!). There's no way to just have the called function magically divine the size, if that's not passed in and there is no explicit, reliable sentinel in use.
Can you try appending a null character \0 to the array and then send it? That way, you can just check for \0 in the loop.
Actually Chucks listing of
for( int i = 0; array[i] != NULL; i++) {
........
}
A sizeof before each call is wasteful and is needed to know what you get.
Works great if you put a NULL at the end of the arrays.
Why?? With embedded designs passing a sizeof in each routine makes each call very large compared to a NULL with each array. I have a 2K PIC16F684 chip and it takes upto 10 percent of the chip with 12 calls using a passed sizeof along with the array. With just the array and Chucks code with NULLS om each array... I get 4 percent needed.
A true case in point.. thanks chuck good call.
I originally had this as an answer to this other question: When a function has a specific-size array parameter, why is it replaced with a pointer?, but just moved it here instead since it more-directly answers this question.
Building off of #Richard Corden's answer and #sbi's answer, here's a larger example demonstrating the principles of:
Enforcing a given function parameter input array size using a reference to an array of a given size, like this:
void foo2(uint8_t (&array)[100])
{
printf("sizeof(array) = %lu\n", sizeof(array));
}
and:
Allowing a function parameter input array of any size, by using a function template with a reference to an input array of a given template parameter size N, like this:
template<size_t N>
void foo3(uint8_t (&array)[N])
{
printf("sizeof(array) = %lu\n", sizeof(array));
}
Looking at the full example below:
Notice how this function prototype doesn't know the array size at all! (the 100 here is simply a visual hint/reminder to the human user, but has no bearing or influence on the compiler whatsoever!):
void foo(uint8_t array[100]) {}
...this function prototype allows only input arrays of a fixed size of 100:
void foo2(uint8_t (&array)[100]) {}
...and this function template prototype allows arrays of ANY input size AND knows their size statically at compile-time (as that is how templates work):
template<size_t N>
void foo3(uint8_t (&array)[N]) {}
Here's the full example:
You can run it yourself here: https://onlinegdb.com/rkyL_tcBv.
#include <cstdint>
#include <cstdio>
void foo(uint8_t array[100])
{
// is ALWAYS sizeof(uint8_t*), which is 8!
printf("sizeof(array) = %lu\n", sizeof(array));
}
void foo2(uint8_t (&array)[100])
{
printf("sizeof(array) = %lu\n", sizeof(array));
}
template<size_t N>
void foo3(uint8_t (&array)[N])
{
printf("sizeof(array) = %lu\n", sizeof(array));
}
int main()
{
printf("Hello World\n");
printf("\n");
uint8_t a1[10];
uint8_t a2[11];
uint8_t a3[12];
// Is `sizeof(array) = 8` for all of these!
foo(a1);
foo(a2);
foo(a3);
printf("\n");
// Fails to compile for these 3! Sample error:
// > main.cpp:49:12: error: invalid initialization of reference of type ‘uint8_t (&)[100]
// > {aka unsigned char (&)[100]}’ from expression of type ‘uint8_t [10] {aka unsigned char [10]}’
// > foo2(a1);
// > ^
// foo2(a1);
// foo2(a2);
// foo2(a3);
// ------------------
// Works just fine for this one since the array `a4` has the right length!
// Is `sizeof(array) = 100`
uint8_t a4[100];
foo2(a4);
printf("\n");
foo3(a1);
foo3(a2);
foo3(a3);
foo3(a4);
printf("\n");
return 0;
}
Sample output:
(compiler warnings, referring to the sizeof call inside foo()):
main.cpp:26:49: warning: ‘sizeof’ on array function parameter ‘array’ will return size of ‘uint8_t* {aka unsigned char*}’ [-Wsizeof-array-argument]
main.cpp:23:27: note: declared here
(stdout "standard output"):
Hello World
sizeof(array) = 8
sizeof(array) = 8
sizeof(array) = 8
sizeof(array) = 100
sizeof(array) = 10
sizeof(array) = 11
sizeof(array) = 12
sizeof(array) = 100
Shouldn't this work? for things like Arduino(AVR) c++ at least.
//rename func foo to foo_ then
#define foo(A) foo_(A, sizeof(A))
void foo_(char a[],int array_size){
...
}
Why isn't the size of an array sent as a parameter the same as within main?
#include <stdio.h>
void PrintSize(int p_someArray[10]);
int main () {
int myArray[10];
printf("%d\n", sizeof(myArray)); /* As expected, 40 */
PrintSize(myArray);/* Prints 4, not 40 */
}
void PrintSize(int p_someArray[10]){
printf("%d\n", sizeof(p_someArray));
}
An array-type is implicitly converted into pointer type when you pass it in to a function.
So,
void PrintSize(int p_someArray[10]) {
printf("%zu\n", sizeof(p_someArray));
}
and
void PrintSize(int *p_someArray) {
printf("%zu\n", sizeof(p_someArray));
}
are equivalent. So what you get is the value of sizeof(int*)
It's a pointer, that's why it's a common implementation to pass the size of the array as a second parameter to the function
As others have stated, arrays decay to pointers to their first element when used as function parameters. It's also worth noting that sizeof does not evaluate the expression and does not require parentheses when used with an expression, so your parameter isn't actually being used at all, so you may as well write the sizeof with the type rather than the value.
#include <stdio.h>
void PrintSize1 ( int someArray[][10] );
void PrintSize2 ( int someArray[10] );
int main ()
{
int myArray[10];
printf ( "%d\n", sizeof myArray ); /* as expected 40 */
printf ( "%d\n", sizeof ( int[10] ) ); /* requires parens */
PrintSize1 ( 0 ); /* prints 40, does not evaluate 0[0] */
PrintSize2 ( 0 ); /* prints 40, someArray unused */
}
void PrintSize1 ( int someArray[][10] )
{
printf ( "%d\n", sizeof someArray[0] );
}
void PrintSize2 ( int someArray[10] )
{
printf ( "%d\n", sizeof ( int[10] ) );
}
So, you will need to pass the lenght of the array as a second parameter. When you are writing code, in which you both declare an array of constant size, and later pass that array to a function, it is a pain to have the array-length constant show up several places in your code...
K&R to the rescue:
#define N_ELEMENTS(array) (sizeof(array)/sizeof((array)[0]))
So now you can do e.g:
int a[10];
...
myfunction(a, N_ELEMENTS(a));
The behavior you found is actually a big wart in the C language. Whenever you declare a function that takes an array parameter, the compiler ignores you and changes the parameter to a pointer. So these declarations all behave like the first one:
void func(int *a)
void func(int a[])
void func(int a
typedef int array_plz[5];
void func(array_plz a)
a will be a pointer to int in all four cases. If you pass an array to func, it will immediately decay into a pointer to its first element. (On a 64-bit system, a 64-bit pointer is twice as large as a 32-bit int, so your sizeof ratio returns 2.)
The only purpose of this rule is to maintain backwards compatibility with historical compilers that did not support passing aggregate values as function arguments.
This does not mean that it’s impossible to pass an array to a function. You can get around this wart by embedding the array into a struct (this is basically the purpose of C++11’s std::array):
struct array_rly {
int a[5];
};
void func(struct array_rly a)
{
printf("%zd\n", sizeof(a.a)/sizeof(a.a[0])); /* prints 5 */
}
or by passing a pointer to the array:
void func(const int (*a)[5])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0])); /* prints 5 */
}
In case the array size isn’t a compile-time constant, you can use the pointer-to-array technique with C99 variable-length arrays:
void func(int n, const int (*a)[n])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0])); /* prints n */
}
Because arrays decay into pointers when they are passed as parameters. This is how C works, although you can pass "arrays" in C++ by reference and overcome this issue. Note that you can pass arrays of different sizes to this function:
// 10 is superfluous here! You can pass an array of different size!
void PrintSize(int p_someArray[10]);
In c++ you can pass an array by reference for this very purpose :
void foo(int (&array)[10])
{
std::cout << sizeof(array) << "\n";
}
In the C language, there is no method to determine the
size of an unknown array, so the quantity needs to
be passed as well as a pointer to the first element.
You can't pass arrays to functions.
If you really wanted to print the size, you could pass a pointer to an array, but it won't be generic at all as you need to define the array size for the function as well.
#include <stdio.h>
void PrintSize(int (*p_anArray)[10]);
int main(void) {
int myArray[10];
printf("%d\n", sizeof(myArray)); /* as expected 40 */
PrintSize(&myArray);/* prints 40 */
}
void PrintSize(int (*p_anArray)[10]){
printf("%d\n", (int) sizeof(*p_anArray));
}
The behavior is by design.
Same syntax in function parameter declaration means completely different thing than in local variable definition.
The reason is described in other answers.
In C language when you pass the array as an argument to the function , it is automatically converted into pointer ,array passing from one function other function is know as call by reference . That is the reason the called function only receives the pointer which point to the first element of function This is the reason
fun(int a[]) is similar to fun(int *a) ;
so when you print the size of array it will print the size of first element.
In 'C' programming languange 'sizeof()' is the operator and he returns the size of the object in bytes.Argument of the 'sizeof()' operator must be a left-value type(integer,float number,struct,array).So if you want to know the size of an array in bytes you can do it very simple.Just use the 'sizeof()' operator and for his argument use the array name.For example:
#include <stdio.h>
main(){
int n[10];
printf("Size of n is: %d \n", sizeof(n));
}
Output on 32 bit system will be: Size of n is: 40.Because ineteger on 32 system is 4bytes.On 64x it is 8bytes.In this case we have 10 integers declared in one array.So the result is '10 * sizeof(int)'.
Some tips:
If we have an array declared like this one 'int n[]={1, 2, 3, ...155..};'.
So we want to know how many elements are stored in this array.
Use this alghorithm:
sizeof(name_of_the_array) / sizeof(array_type)
Code: #include
main(){
int n[] = { 1, 2, 3, 44, 6, 7 };
printf("Number of elements: %d \n", sizeof(n) / sizeof(int));
return 0;
}
Arrays are only loosely sized. For the most part, an array is a pointer to memory. The size in your declaration only tells the compiler how much memory to allocate for the array - it's not associated with the type, so sizeof() has nothing to go on.
Is it possible to determine the size of an array if it was passed to another function (size isn't passed)? The array is initialized like int array[] = { XXX } ..
I understand that it's not possible to do sizeof since it will return the size of the pointer .. Reason I ask is because I need to run a for loop inside the other function where the array is passed. I tried something like:
for( int i = 0; array[i] != NULL; i++) {
........
}
But I noticed that at the near end of the array, array[i] sometimes contain garbage values like 758433 which is not a value specified in the initialization of the array..
The other answers overlook one feature of c++. You can pass arrays by reference, and use templates:
template <typename T, int N>
void func(T (&a) [N]) {
for (int i = 0; i < N; ++i) a[i] = T(); // reset all elements
}
then you can do this:
int x[10];
func(x);
but note, this only works for arrays, not pointers.
However, as other answers have noted, using std::vector is a better choice.
If it's within your control, use a STL container such as a vector or deque instead of an array.
Nope, it's not possible.
One workaround: place a special value at the last value of the array so you can recognize it.
One obvious solution is to use STL. If it's not a possibility, it's better to pass array length explicitly.
I'm skeptical about use the sentinel value trick, for this particular case. It works
better with arrays of pointers, because NULL is a good value for a sentinel. With
array of integers, it's not that easy - you need to have
a "magic" sentinel value, which is
not good.
Side note: If your array is defined and initalized as
int array[] = { X, Y, Z };
in the same scope as your loop, then
sizeof(array) will return it's real size in bytes, not the size of the pointer. You can get the array length as
sizeof(array) / sizeof(array[0])
However, in general case, if you get array as a pointer, you can't use this trick.
You could add a terminator to your int array then step through the array manually to discover the size within the method.
#include<iostream>
using namespace std;
int howBigIsBareArray(int arr[]){
int counter = 0;
while (arr[counter] != NULL){
counter++;
}
return counter;
}
int main(){
int a1[6] = {1,2,3,4,5,'\0'};
cout << "SizeOfMyArray: " << howBigIsBareArray(a1);
}
This program prints:
SizeOfMyArray: 5
This is an O(n) time complexity operation which is bad. You should never be stepping through an array just to discover its size.
If you can't pass the size, you do need a distinguishable sentinel value at the end (and you need to put it there yourself -- as you've found, you can't trust C++ to do it automagically for you!). There's no way to just have the called function magically divine the size, if that's not passed in and there is no explicit, reliable sentinel in use.
Can you try appending a null character \0 to the array and then send it? That way, you can just check for \0 in the loop.
Actually Chucks listing of
for( int i = 0; array[i] != NULL; i++) {
........
}
A sizeof before each call is wasteful and is needed to know what you get.
Works great if you put a NULL at the end of the arrays.
Why?? With embedded designs passing a sizeof in each routine makes each call very large compared to a NULL with each array. I have a 2K PIC16F684 chip and it takes upto 10 percent of the chip with 12 calls using a passed sizeof along with the array. With just the array and Chucks code with NULLS om each array... I get 4 percent needed.
A true case in point.. thanks chuck good call.
I originally had this as an answer to this other question: When a function has a specific-size array parameter, why is it replaced with a pointer?, but just moved it here instead since it more-directly answers this question.
Building off of #Richard Corden's answer and #sbi's answer, here's a larger example demonstrating the principles of:
Enforcing a given function parameter input array size using a reference to an array of a given size, like this:
void foo2(uint8_t (&array)[100])
{
printf("sizeof(array) = %lu\n", sizeof(array));
}
and:
Allowing a function parameter input array of any size, by using a function template with a reference to an input array of a given template parameter size N, like this:
template<size_t N>
void foo3(uint8_t (&array)[N])
{
printf("sizeof(array) = %lu\n", sizeof(array));
}
Looking at the full example below:
Notice how this function prototype doesn't know the array size at all! (the 100 here is simply a visual hint/reminder to the human user, but has no bearing or influence on the compiler whatsoever!):
void foo(uint8_t array[100]) {}
...this function prototype allows only input arrays of a fixed size of 100:
void foo2(uint8_t (&array)[100]) {}
...and this function template prototype allows arrays of ANY input size AND knows their size statically at compile-time (as that is how templates work):
template<size_t N>
void foo3(uint8_t (&array)[N]) {}
Here's the full example:
You can run it yourself here: https://onlinegdb.com/rkyL_tcBv.
#include <cstdint>
#include <cstdio>
void foo(uint8_t array[100])
{
// is ALWAYS sizeof(uint8_t*), which is 8!
printf("sizeof(array) = %lu\n", sizeof(array));
}
void foo2(uint8_t (&array)[100])
{
printf("sizeof(array) = %lu\n", sizeof(array));
}
template<size_t N>
void foo3(uint8_t (&array)[N])
{
printf("sizeof(array) = %lu\n", sizeof(array));
}
int main()
{
printf("Hello World\n");
printf("\n");
uint8_t a1[10];
uint8_t a2[11];
uint8_t a3[12];
// Is `sizeof(array) = 8` for all of these!
foo(a1);
foo(a2);
foo(a3);
printf("\n");
// Fails to compile for these 3! Sample error:
// > main.cpp:49:12: error: invalid initialization of reference of type ‘uint8_t (&)[100]
// > {aka unsigned char (&)[100]}’ from expression of type ‘uint8_t [10] {aka unsigned char [10]}’
// > foo2(a1);
// > ^
// foo2(a1);
// foo2(a2);
// foo2(a3);
// ------------------
// Works just fine for this one since the array `a4` has the right length!
// Is `sizeof(array) = 100`
uint8_t a4[100];
foo2(a4);
printf("\n");
foo3(a1);
foo3(a2);
foo3(a3);
foo3(a4);
printf("\n");
return 0;
}
Sample output:
(compiler warnings, referring to the sizeof call inside foo()):
main.cpp:26:49: warning: ‘sizeof’ on array function parameter ‘array’ will return size of ‘uint8_t* {aka unsigned char*}’ [-Wsizeof-array-argument]
main.cpp:23:27: note: declared here
(stdout "standard output"):
Hello World
sizeof(array) = 8
sizeof(array) = 8
sizeof(array) = 8
sizeof(array) = 100
sizeof(array) = 10
sizeof(array) = 11
sizeof(array) = 12
sizeof(array) = 100
Shouldn't this work? for things like Arduino(AVR) c++ at least.
//rename func foo to foo_ then
#define foo(A) foo_(A, sizeof(A))
void foo_(char a[],int array_size){
...
}
Is it possible to determine the size of an array if it was passed to another function (size isn't passed)? The array is initialized like int array[] = { XXX } ..
I understand that it's not possible to do sizeof since it will return the size of the pointer .. Reason I ask is because I need to run a for loop inside the other function where the array is passed. I tried something like:
for( int i = 0; array[i] != NULL; i++) {
........
}
But I noticed that at the near end of the array, array[i] sometimes contain garbage values like 758433 which is not a value specified in the initialization of the array..
The other answers overlook one feature of c++. You can pass arrays by reference, and use templates:
template <typename T, int N>
void func(T (&a) [N]) {
for (int i = 0; i < N; ++i) a[i] = T(); // reset all elements
}
then you can do this:
int x[10];
func(x);
but note, this only works for arrays, not pointers.
However, as other answers have noted, using std::vector is a better choice.
If it's within your control, use a STL container such as a vector or deque instead of an array.
Nope, it's not possible.
One workaround: place a special value at the last value of the array so you can recognize it.
One obvious solution is to use STL. If it's not a possibility, it's better to pass array length explicitly.
I'm skeptical about use the sentinel value trick, for this particular case. It works
better with arrays of pointers, because NULL is a good value for a sentinel. With
array of integers, it's not that easy - you need to have
a "magic" sentinel value, which is
not good.
Side note: If your array is defined and initalized as
int array[] = { X, Y, Z };
in the same scope as your loop, then
sizeof(array) will return it's real size in bytes, not the size of the pointer. You can get the array length as
sizeof(array) / sizeof(array[0])
However, in general case, if you get array as a pointer, you can't use this trick.
You could add a terminator to your int array then step through the array manually to discover the size within the method.
#include<iostream>
using namespace std;
int howBigIsBareArray(int arr[]){
int counter = 0;
while (arr[counter] != NULL){
counter++;
}
return counter;
}
int main(){
int a1[6] = {1,2,3,4,5,'\0'};
cout << "SizeOfMyArray: " << howBigIsBareArray(a1);
}
This program prints:
SizeOfMyArray: 5
This is an O(n) time complexity operation which is bad. You should never be stepping through an array just to discover its size.
If you can't pass the size, you do need a distinguishable sentinel value at the end (and you need to put it there yourself -- as you've found, you can't trust C++ to do it automagically for you!). There's no way to just have the called function magically divine the size, if that's not passed in and there is no explicit, reliable sentinel in use.
Can you try appending a null character \0 to the array and then send it? That way, you can just check for \0 in the loop.
Actually Chucks listing of
for( int i = 0; array[i] != NULL; i++) {
........
}
A sizeof before each call is wasteful and is needed to know what you get.
Works great if you put a NULL at the end of the arrays.
Why?? With embedded designs passing a sizeof in each routine makes each call very large compared to a NULL with each array. I have a 2K PIC16F684 chip and it takes upto 10 percent of the chip with 12 calls using a passed sizeof along with the array. With just the array and Chucks code with NULLS om each array... I get 4 percent needed.
A true case in point.. thanks chuck good call.
I originally had this as an answer to this other question: When a function has a specific-size array parameter, why is it replaced with a pointer?, but just moved it here instead since it more-directly answers this question.
Building off of #Richard Corden's answer and #sbi's answer, here's a larger example demonstrating the principles of:
Enforcing a given function parameter input array size using a reference to an array of a given size, like this:
void foo2(uint8_t (&array)[100])
{
printf("sizeof(array) = %lu\n", sizeof(array));
}
and:
Allowing a function parameter input array of any size, by using a function template with a reference to an input array of a given template parameter size N, like this:
template<size_t N>
void foo3(uint8_t (&array)[N])
{
printf("sizeof(array) = %lu\n", sizeof(array));
}
Looking at the full example below:
Notice how this function prototype doesn't know the array size at all! (the 100 here is simply a visual hint/reminder to the human user, but has no bearing or influence on the compiler whatsoever!):
void foo(uint8_t array[100]) {}
...this function prototype allows only input arrays of a fixed size of 100:
void foo2(uint8_t (&array)[100]) {}
...and this function template prototype allows arrays of ANY input size AND knows their size statically at compile-time (as that is how templates work):
template<size_t N>
void foo3(uint8_t (&array)[N]) {}
Here's the full example:
You can run it yourself here: https://onlinegdb.com/rkyL_tcBv.
#include <cstdint>
#include <cstdio>
void foo(uint8_t array[100])
{
// is ALWAYS sizeof(uint8_t*), which is 8!
printf("sizeof(array) = %lu\n", sizeof(array));
}
void foo2(uint8_t (&array)[100])
{
printf("sizeof(array) = %lu\n", sizeof(array));
}
template<size_t N>
void foo3(uint8_t (&array)[N])
{
printf("sizeof(array) = %lu\n", sizeof(array));
}
int main()
{
printf("Hello World\n");
printf("\n");
uint8_t a1[10];
uint8_t a2[11];
uint8_t a3[12];
// Is `sizeof(array) = 8` for all of these!
foo(a1);
foo(a2);
foo(a3);
printf("\n");
// Fails to compile for these 3! Sample error:
// > main.cpp:49:12: error: invalid initialization of reference of type ‘uint8_t (&)[100]
// > {aka unsigned char (&)[100]}’ from expression of type ‘uint8_t [10] {aka unsigned char [10]}’
// > foo2(a1);
// > ^
// foo2(a1);
// foo2(a2);
// foo2(a3);
// ------------------
// Works just fine for this one since the array `a4` has the right length!
// Is `sizeof(array) = 100`
uint8_t a4[100];
foo2(a4);
printf("\n");
foo3(a1);
foo3(a2);
foo3(a3);
foo3(a4);
printf("\n");
return 0;
}
Sample output:
(compiler warnings, referring to the sizeof call inside foo()):
main.cpp:26:49: warning: ‘sizeof’ on array function parameter ‘array’ will return size of ‘uint8_t* {aka unsigned char*}’ [-Wsizeof-array-argument]
main.cpp:23:27: note: declared here
(stdout "standard output"):
Hello World
sizeof(array) = 8
sizeof(array) = 8
sizeof(array) = 8
sizeof(array) = 100
sizeof(array) = 10
sizeof(array) = 11
sizeof(array) = 12
sizeof(array) = 100
Shouldn't this work? for things like Arduino(AVR) c++ at least.
//rename func foo to foo_ then
#define foo(A) foo_(A, sizeof(A))
void foo_(char a[],int array_size){
...
}