Determining the quantity of elements in a C array - c++

When print_array is called, the size of the int array[] parameter (count) isn't what was expected. It seems sizeof is not returning the size of the entire array which would be 5*sizeof(int) = 20.
namespace Util
{
void print_array(int array[])
{
size_t count = (sizeof array)/(sizeof array[0]);
cout << count;
// int count = sizeof(array)/sizeof(array[0]);
// for (int i = 0; i <= count; i++) cout << array[i];
}
}
int array_test[5]={2,1,5,4,3};
Util::print_array(array_test);

int array[] here becomes int* array, and sizeof(array) returns the same thing sizeof(int*). You need to pass an array by reference to avoid that.
template <size_t N>
void print_array(int (&array)[N]) {
std::cout << N;
}
int array[] = { 2, 1, 5, 4, 3 };
print_array(array);

Read this: it says the way to fix this, but for a quick description:
When a function has a specific-size array parameter, why is it replaced with a pointer?
Using sizeof(array) will work in the scope that the array is statically defined in. When you pass it into a function though the type gets converted into a pointer to the array element type. In your case, when you're in print_array it is an int*. So, your sizeof in in the function will be the size of a pointer on your system (likely 32 or 64 bits).
You can get around this with some fancy syntax like so (from the link above):
If you want that the array type is preserved, you should pass in a
reference to the array:
void foo ( int(&array)[5] );
but I'd say just pass the size in as well as another parameter, its more readable.

As this array is implemented as a thin overlay on pointers, the variable you have is just a pointer, so sizeof will return the size of your pointer.
The only way to know the length of an array is to place a terminating object, as the null character in C strings.
There is no other way to determine the size of an array if you only have a pointer to it.

Here's a trick: you can take a reference to an array of fixed size. You can use this to template-deduce the size.
#include <iostream>
char a [22];
char b [33];
void foo (char *, size_t size)
{
std :: cout << size << "\n";
}
template <size_t N>
void foo (char (&x) [N])
{
foo (x, N);
}
int main () {
foo (a);
foo (b);
}
This prints 22\n33\n

void print_array( int array[] ) is synonymous with void print_array( int *array ). No size information is passed when the function call is made, so sizeof doesn't work here.

For an algorithm like this, I like to use iterators, then you can do what you want... e.g.
template <typename Iterator>
void print(Interator begin, Iterator end)
{
std::cout << "size: " << std::distance(begin, end) << std::endl;
std::copy(begin, end, std::ostream_iterator<std::iterator_traits<Iterator>::value_type>(std::cout, ", "));
}
to call
print(a, a + 5); // can calculate end using the sizeof() stuff...

just an addition to all the answers already posted:
if you want to use an array which is more comfortable (like an ArrayList in java for instance) then just use the stl-vector container which is also able to return its size

All the following declarations are exactly same:
void print_array(int array[]);
void print_array(int array[10]);
void print_array(int array[200]);
void print_array(int array[1000]);
void print_array(int *array);
That means, sizeof(array) would return the value of sizeof(int*), in all above cases, even in those where you use integers (they're ignored by the compiler, in fact).
However, all the following are different from each other, and co-exist in a program, at the same time:
void print_array(int (&array)[10]);
void print_array(int (&array)[200]);
void print_array(int (&array)[1000]);
int a[10], b[200], c[1000], d[999];
print_array(a); //ok - calls the first function
print_array(b); //ok - calls the second function
print_array(c); //ok - calls the third function
print_array(d); //error - no function accepts int array of size 999

Related

How to convert an array decay to a pointer into a vector without knowing the array size? [duplicate]

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){
...
}

C++ std::copy error: request for member ‘end’ in ‘__cont’, which is of non-class type ‘int* const’ [duplicate]

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){
...
}

Checking size of an array through function

When I want to know the size of an array I do the following :
int array[30];
for(int i = 0; i < 30; i++)
array[i] = i+1; //Fill list
const int size = sizeof(array) / sizeof(array[0]);
But when I pass the array as argument in a function I will have a pointer in the function.
int size( int array[] )
{
return sizeof(array) / sizeof(array[0]); //Doesn't work anymore
}
This obviously doesn't work. But how do I get the size of that array in a function without taking another parameter for the size?
how do I get the size of that array in a function without taking
another parameter for the size?
You don't. The size of the array has to be somewhere visible to the compiler. Otherwise all you'll be able to pass is a pointer to the first element in the array.
However, you can use a template for the size, and make this a little more magical and seamless:
template <size_t N> int size (const int (&ary)[N])
{
assert (N == (sizeof(ary) / sizeof (ary[0])));
return N;
}
And further templatizing the type of elements, so this works with arrays of anything:
template <typename T, size_t N> int size (const T (&ary)[N])
{
assert (N == (sizeof(ary) / sizeof (ary[0])));
return N;
}
This is the way to get the size of the array using function templates:
template <typename T, size_t N>
constexpr size_t size(const T (&)[N] ) // omit constexpr if no C++11 support
{
return N
}
then
for(int i = 0; i < size(array); i++) { .... }
but you could simplify things by using an std::array (or std::tr1::array or boost::array if you don't have C++11) and using it's size() method.
In C, arrays in function parameters behave very strangely. Frankly, I think the language was very badly designed here.
void foo(int data[10]) {
int *p;
int a[10];
}
sizeof(p) will probably be 4 (or maybe 8). And sizeof(a) will be 40 (or 80).
So what do you think sizeof(data) will be? If you guessed 40 (or 80), you're wrong. Instead, its size is the same as sizeof(p).
If a C compiler see a [ immediately after the name of a parameter, it removes it and replaces it with a pointer, and data[10] becomes *data. (This is different from the decaying behaviour we get with arrays elsewhere, when a parameter, arrays are dealt with more drastically).
In fact, the following will compile despite the different sized arrays:
int foo(int data[10]);
int main() {
int hugearray[1000];
foo(hugearray); // this compiles!
}
The C compiler doesn't respect, in any way, the size of array parameters. I believe that compilers should issue a warning on any array parameters, and encourage us to use the * directly. I might allow [], but certainly not [10] given that it's ignored by the compiler.
If you want your C compiler to respect the size of arrays, you should pass the address of the array.
int foo(int (*data)[10]);
int main() {
int smallarray[10];
foo(&smallarray); // OK
int hugearray[1000];
foo(&hugearray); // error, as desired
}
Returning to the original question, parameter arrays know nothing about their size.
Use Macro
int findSize(int array[])
{
//This will not return size off array,it will just get starting address array and no information about boundaries
return sizeof(array) / sizeof(array[0]);
}
//But we can define a Macro for this
#define FIND_ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
int main()
{
int SampleArray[30];
printf("\nSize =%d ",sizeof(SampleArray) / sizeof(SampleArray[0]));
printf("\nSize from Function =%d ",findSize(SampleArray));
printf("\nSize from Macro =%d ",FIND_ARRAY_SIZE(SampleArray));
printf("\n");
return 0;
}
In C you can't find the size of array by passing array beginning address to function.
For example You have made function call
size(array); // You are calling function by passing address of array beginning element
int size( int array[] ) // this is same as int size(int *array)
{
return sizeof(array) / sizeof(array[0]); //Doesn't work anymore
}
Here sizeof(array) will give you the size of pointer. that is architecture dependent.
And if you pass character array instead of int array and that too if the character array was nulterminated then You can use strlen().This is the only way we can find the size of array.
strlen() counts till nul occurrence, You can use this trick However allocate memory for one more element to your array or declare your array with MAX_SIZE+1 .When ever if you store array elements of size n then store a known value inside array[n] and while finding size check against that value like strlen() Checks for Nul character.

How to find the size of an int[]? [duplicate]

This question already has answers here:
How do I find the length of an array?
(30 answers)
Closed 2 years ago.
I have
int list[] = {1, 2, 3};
How to I get the size of list?
I know that for a char array, we can use strlen(array) to find the size, or check with '\0' at the end of the array.
I tried sizeof(array) / sizeof(array[0]) as some answers said, but it only works in main? For example:
int size(int arr1[]){
return sizeof(arr1) / sizeof(arr1[0]);
}
int main() {
int list[] = {1, 2, 3};
int size1 = sizeof(list) / sizeof(list[0]); // ok
int size2 = size(list_1); // no
// size1 and size2 are not the same
}
Why?
Try this:
sizeof(list) / sizeof(list[0]);
Because this question is tagged C++, it is always recommended to use std::vector in C++ rather than using conventional C-style arrays.
An array-type is implicitly converted into a pointer-type when you pass it to a function.
Have a look at this.
In order to correctly print the sizeof an array inside any function, pass the array by reference to that function (but you need to know the size of that array in advance).
You would do it like so for the general case
template<typename T,int N>
//template argument deduction
int size(T (&arr1)[N]) //Passing the array by reference
{
return sizeof(arr1)/sizeof(arr1[0]); //Correctly returns the size of 'list'
// or
return N; //Correctly returns the size too [cool trick ;-)]
}
The "standard" C way to do this is
sizeof(list) / sizeof(list[0])
You could use boost::size, which is basically defined this way:
template <typename T, std::size_t N>
std::size_t size(T const (&)[N])
{
return N;
}
Note that if you want to use the size as a constant expression, you'll either have to use the sizeof a / sizeof a[0] idiom or wait for the next version of the C++ standard.
You can't do that for a dynamically allocated array (or a pointer). For static arrays, you can use sizeof(array) to get the whole array size in bytes and divide it by the size of each element:
#define COUNTOF(x) (sizeof(x)/sizeof(*x))
To get the size of a dynamic array, you have to keep track of it manually and pass it around with it, or terminate it with a sentinel value (like '\0' in null terminated strings).
Update: I realized that your question is tagged C++ and not C. You should definitely consider using std::vector instead of arrays in C++ if you want to pass things around:
std::vector<int> v;
v.push_back(1);
v.push_back(2);
std::cout << v.size() << std::endl; // prints 2
Since you've marked this as C++, it's worth mentioning that there is a somewhat better way than the C-style macro:
template <class T, size_t N>
size_t countof(const T &array[N]) { return N; }
This has the advantage that if you accidentally try to pass something other than an array to it, the code simply won't compile (whereas passing a pointer to the C macro will compile but produce a bad result. The disadvantage is that this doesn't give you a compile-time constant, so you can't do something like this:
int a[20];
char x[countof(a)];
In C++11 or newer, you can add constexpr to get a compile-time constant:
template <class T, size_t N>
constexpr size_t countof(const T &array[N]) { return N; }
If you really want to support the same on older compilers, there is a way, originally invented by Ivan Johnson, AFAIK:
#define COUNTOF(x) ( \
0 * sizeof( reinterpret_cast<const ::Bad_arg_to_COUNTOF*>(x) ) + \
0 * sizeof( ::Bad_arg_to_COUNTOF::check_type((x), &(x)) ) + \
sizeof(x) / sizeof((x)[0]) )
class Bad_arg_to_COUNTOF
{
public:
class Is_pointer;
class Is_array {};
template<typename T>
static Is_pointer check_type(const T*, const T* const*);
static Is_array check_type(const void*, const void*);
};
This uses sizeof(x)/sizeof(x[0]) to compute the size, just like the C macro does, so it gives a compile-time constant. The difference is that it first uses some template magic to cause a compile error if what you've passed isn't the name of an array. It does that by overloading check_type to return an incomplete type for a pointer, but a complete type for an array. Then (the really tricky part) it doesn't actually call that function at all -- it just takes the size of the type the function would return, which is zero for the overload that returns the complete type, but not allowed (forcing a compile error) for the incomplete type.
IMO, that's a pretty cool example of template meta programming -- though in all honesty, the result is kind of pointless. You really only need that size as a compile time constant if you're using arrays, which you should normally avoid in any case. Using std::vector, it's fine to supply the size at run-time (and resize the vector when/if needed).
Besides Carl's answer, the "standard" C++ way is not to use a C int array, but rather something like a C++ STL std::vector<int> list which you can query for list.size().
when u pass any array to some function. u are just passing it's starting address, so for it to work u have to pass it size also for it to work properly. it's the same reason why we pass argc with argv[] in command line arguement.
You can make a template function, and pass the array by reference to achieve this.
Here is my code snippet
template <typename TypeOfData>
void PrintArray(TypeOfData &arrayOfType);
int main()
{
char charArray[] = "my name is";
int intArray[] = { 1,2,3,4,5,6 };
double doubleArray[] = { 1.1,2.2,3.3 };
PrintArray(charArray);
PrintArray(intArray);
PrintArray(doubleArray);
}
template <typename TypeOfData>
void PrintArray(TypeOfData &arrayOfType)
{
int elementsCount = sizeof(arrayOfType) / sizeof(arrayOfType[0]);
for (int i = 0; i < elementsCount; i++)
{
cout << "Value in elements at position " << i + 1 << " is " << arrayOfType[i] << endl;
}
}
You have to use sizeof() function.
Code Snippet:
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
int arr[] ={5, 3, 6, 7};
int size = sizeof(arr) / sizeof(arr[0]);
cout<<size<<endl;
return 0;
}
int arr1[] = {8, 15, 3, 7};
int n = sizeof(arr1)/sizeof(arr1[0]);
So basically sizeof(arr1) is giving the size of the object being pointed to, each element maybe occupying multiple bits so dividing by the number of bits per element (sizeof(arr1[0]) gives you the actual number of elements you're looking for, i.e. 4 in my example.
This method work when you are using a class: In this example you will receive a array, so the only method that worked for me was these one:
template <typename T, size_t n, size_t m>
Matrix& operator= (T (&a)[n][m])
{
int arows = n;
int acols = m;
p = new double*[arows];
for (register int r = 0; r < arows; r++)
{
p[r] = new double[acols];
for (register int c = 0; c < acols; c++)
{
p[r][c] = a[r][c]; //A[rows][columns]
}
}
https://www.geeksforgeeks.org/how-to-print-size-of-an-array-in-a-function-in-c/
Assuming you merely want to know the size of an array whose type you know (int) but whose size, obviously, you don't know, it is suitable to verify whether the array is empty, otherwise you will end up with a division by zero (causing a Float point exception).
int array_size(int array[]) {
if(sizeof(array) == 0) {
return 0;
}
return sizeof(array)/sizeof(array[0]);
}
If you want to know how much numbers the array have, you want to know the array length. The function sizeof(var) in C gives you the bytes in the computer memory. So if you know the memory the int occupy you can do like this:
int arraylength(int array[]) {
return sizeof(array) / sizeof(int); // Size of the Array divided by the int size
}

determine size of array if passed to function

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){
...
}