confusion determining element number of an array - c++

I've heard from my lecturer, sizeof(some pointer) always equal in a machine. For example, if it is 64 bit all pointers are 8 byte, in 32 bit 4 byte. So, I like to use sizeof when I want to specify size of an array like
int arr[] = {2, 5, -1, 10, 9};
int size = sizeof(arr) / sizeof(int)
I assume that above code an int takes 4, so 20/4 gives number of elements for arr.
int arr[] = {2, 5, -1, 10, 9};
int size = sizeof(arr) / sizeof(int*)
I also assume that sizeof(some pointer) takes 4, so 20/4 again gives number of elements for arr.
I'm confused that when I apply it for a double array. I think it shouldn't work. But, it works.
double arr[] = {2, 5, -1, 10, 9};
int size = sizeof(arr) / sizeof(double*);
If every pointers take same size in a machine, how can be the result right? Can be the question explained?
Edit
I mixed up division by *arr and double pointer

Size of a pointer is not the size of the type of the elements in the double array, because the elements are doubles not pointers.
When you apply sizeof to an array it gives the size of the array in bytes, in case of
double arr[] = {2, 5, -1, 10, 9};
it's
5 * sizeof(double)
and sizeof(double) != sizeof(double *). So to actually get the number of elements in the array you need
sizeof(arr) / sizeof(double);
but to make it more maintainable, you can just ask for the size of the type of the elements like this
sizeof(arr) / sizeof(*arr);
or
sizeof(arr) / sizeof(arr[0]);
Also, do not rely on this method to determine the number of elements in an array. Note that at runtime there is no way to know that from the array itself in c, since it's not stored with the array. You need to store the value if you want to keep track of the number of elements.
While this might seem annoying when you first think of it, with the experience you should learn that, it's better this way. Because it gives you complete control over what data your program has to handle, and once you get used to it, it will become very hard to trust languages that just give you the length of the array like python's len operator.

Related

Calculating an array's number of elements... Able to refer to its index values by just stating the return type? What? How? Why? (C++)

I am learning how to calculate the size and number of elements in an array and came across a question. In a tutorial I see
we can calculate the number of elements in an array as follows ...
int array_variable [] = {1, 5, 8, 10};
int array_variable_number_of_elements = sizeof(array_variable) / sizeof (int);
I am aware and fully understand why you could replace
sizeof (int);
with
sizeof (array_variable[0]); // or use any index value from the array_variable
The video appears to suggest using just int is good practice which I don't understand. The computer obviously isn't psychic and int is simply a data type. What happens when there are two int type arrays in the same function? Why does this work? Does this work because it is in the same line as the following?
int array_variable_number_of_elements = sizeof(array_variable)
Thanks :)
Second approach is better and more generic, when you need to change the type of array int to char, you don't have to edit second line at all.
char array_variable [] = {'a', 'b', 'c' }; //changed this line only
int array_variable_number_of_elements = sizeof(array_variable) / sizeof
(array_variable[0]);
To answer your below comment;
above lines you can interpret like below;
int array_variable = {1, 2, 3, 4, 5 };
int array_variable_number_of_elements = sizeof(array_variable) / sizeof ( int);
// ^^^^^^^^^ ^^^^ ^^^
// array_variable_number_of_elements = 20 / 4 ; // 20 / 4 = 5
total array size in bytes 20 and size of int is 4 bytes in my system;
total number of elements in array is 5;

How does C++ find the size of an array?

Difference From Other Questions
I am not asking how to find the size, but how the computer finds the size.
Goal
I want to find out how C++ finds the size of an array (using sizeof(array)), and a 2D array (using sizeof(array)).
When I ran the code, I thought the output would be 3 and 6. But it was 12 and 24!? How do I make the the output 3 and 6?
I don't know how to calculate the size of an array, so when I say "an output of three/six", I mean the amount of numbers in the array.
Code
#include <iostream>
using namespace std;
int main()
{
int oneDArray [3] = {1, 2, 3};
int twoDArray [2][3] = {{1, 2, 3}, {1, 2, 3}};
cout << sizeof(oneDArray) << "\n" << sizeof(twoDArray);
return 0;
}
The sizeof operator returns the size in bytes, not elements.
For single dimensional arrays (not passed as a function argument, which would cause decay to a pointer), you can get the element count by dividing the size of the array by the size of the first element, e.g.
sizeof(oneDArray) / sizeof(oneDArray[0]) // Gets 3
For multidimensional arrays, that would tell you the size of the first dimension, not the number of elements total, so you'd need to drill down deeper:
sizeof(twoDArray) / sizeof(twoDArray[0]) // Gets 2 (first dimension of array)
sizeof(twoDArray) / sizeof(twoDArray[0][0]) // Gets 6 (number of elements)
You can of course explicitly name the type of an element to avoid nested indexing (sizeof(twoDArray) / sizeof(int) get 6 just fine), but I avoid it as a rule; it's too common for an array to change types during development (say, it turns out you need to use int64_t because you have values into the trillions), and if the whole expression isn't in terms of the array, it's easy to overlook it and end up with broken code.
sizeof returns bytes, if you expect number of elements, divide by the size of each element
cout << sizeof(oneDArray)/sizeof(int) << "\n" << sizeof(twoDArray)/sizeof(int);
Output:
3
6

How do sizeof(arr) / sizeof(arr[0]) work?

When looking for a size of an array in a for loop I've seen people write
int arr[10];
for(int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++){}
How is sizeof(arr) / sizeof(arr[0]) the length of the array? How does it technically work?
If you have an array then sizeof(array) returns the number of bytes the array occupies. Since each element can take more than 1 byte of space, you have to divide the result with the size of one element (sizeof(array[0])). This gives you number of elements in the array.
Example:
std::uint32_t array[10];
auto sizeOfInt = sizeof(std::uint32_t); // 4
auto numOfBytes = sizeof(array); // 10*sizeOfInt = 40
auto sizeOfElement = sizeof(array[0]); // sizeOfInt = 4
auto numOfElements = sizeof(array) / sizeof(array[0]); // numOfBytes / sizeOfElement = 40 / 4 = 10
LIVE EXAMPLE
Note that if you pass an array to a function, the above won't work since the array decays to a pointer and sizeof(array) returns the size of the pointer.
std::size_t function(std::uint32_t a[]) // same for void function(std::uint32_t a[10])
{
return sizeof(a); // sizeof(std::uint32_t*)!
}
std::uint32_t array[10];
auto sizeOfArray = function(array); // array decays to a pointer inside function()
LIVE EXAMPLE #2
As it is described in the C++ Standard (5.3.3 Sizeof)
1 The sizeof operator yields the number of bytes in the object
representation of its operand. The operand is either an expression,
which is an unevaluated operand (Clause 5), or a parenthesized
type-id.
In this expression
sizeof(arr) / sizeof(arr[0])
there are used two subexpressions with the sizeof operator.
This subexpression
sizeof(arr)
yields the number of bytes occupied by array arr (I suppose that arr is an array).
For example if you declared an array like
int arr[10];
then the compiler has to reserve memory that to hold 10 elements of type int. If for example sizeof( int ) is equal to 4 then the compiler will reserve 10 * 4 = 40 bytes of memory.
Subexpression
sizeof(arr[0])
gives the number of bytes occupied by one element in the array. You could use any index as for example
sizeof(arr[1000])
because the expression is unevaluated. It is only important the size in bytes of the object (an element of the array) used inside the operator.
Thus if you know the total bytes that were reserved for an array
sizeof(arr)
and know how many bytes each element of the array occupies (all elements of an array have the same size) then you can calculate the number of elements in the array by using the formula
sizeof(arr) / sizeof(arr[0])
Here is a simple relation. If you have an array of N elements of type T
T arr[N];
and you know the size of the memory occupied by the array then you can calculate the size of its element by using formula
sizeof( arr ) / N == size of an element of the array.
And vice verse
If you know the size of the memory occupied by the array and the size of its element you can calculate the number of elements in the array
sizeof( arr ) / sizeof( a[0] ) == N - number of elements in the array
The last expression you can rewrite also the following way
sizeof( arr ) / sizeof( T ) == N - number of elements in the array
because the elements of the array have type T and each element of the array occupies exactly the number of bytes that are required to allocate an object of type T.
Take into acccount that usually beginners make such an error. They pass an array as an argument to a function. For example let's assume that you have a function
void f( int a[] )
{
// ...
}
And you pass to the function your array
int arr[10];
f(arr);
then the function uses the pointer to the first element of the array. In fact the function has declaration
void f( int *a )
{
// ...
}
So if you write for example within the function
void f( int *a )
{
size_t n = sizeof( a ) / sizeof( a[0] );
// ...
}
then as a within the function is a pointer (it is not an array) then you will get something like
void f( int *a )
{
size_t n = sizeof( int * ) / sizeof( int );
// ...
}
Usually the size of a pointer equal to either 8 or 4 bytes depending of the used environment. And you won't get the number of elements. You will get some weird value.
int - is equal to 4 bytes
sizeof(int) it means: 1 * 4 = 4
int arr[10] - is holding 10 int
sizeof(arr) it means: 10 * 4 = 40, we got 10 int and every int got 4 bytes,, arr without the [] it means all the arr.
sizeof(arr[0]) it means: 1 * 4 = 4
sizeof(arr) / sizeof(arr[0]) = 10*4 / 1*4 = 10,, and it is the length of the array.
It only works if arr has not been decayed into a pointer, that is, it is an array type, not a pointer type.
sizeof(arr) is the total size occupied by the array.
sizeof(arr[0]) is the size of the first element in the array. (Note that zero length arrays are not permitted in C++ so this element always exists if the array itself exists).
Since all the elements will be of the same size, the number of elements is sizeof(arr) / sizeof(arr[0]).
When dealing with an array (some_type name[some_size]) sizeof(name) is how many bytes the array occupies. Dividing the total size of the array by the size of one element (sizeof(name[0])) gives you how many elements are in the array.
c++ way to use extent, which allows u to get a number of elements in Nth dimension of the array.
see http://en.cppreference.com/w/cpp/types/extent for details
int values[] = { 1 };
std::extent<decltype(values)>::value == 1
Let's take an example like the arr[]={1,2,4,3,5}.
Then the size of the array will be 5 and the size of arr[0] will be "1" BECAUSE it consists of an element in it. Basically it's a subarray the from the above problem it will be 5/1 it will automatically returns the size of array =5.
The difference is
int arr[5] = {1,2,3,4,5};
here arr is Pointer to array and &arr[0] is pointer of type Integer

Logical Size (number of elements) in array

I have an array (defined below) and I want to find the number of elements in it and send in mehtod call.
So, I have this:
const int MAX_SIZE = 20; // Maximum size of data array
double givenDataPoints[MAX_SIZE] = {0, 2, 3.8, 5, 9, 16, 16.2, 17, 18, 19, 19.5};
And i want to get
int logicalSize = //this should be 10 because I only put in 10 numbers, not 20
How do I do this?
I highly recommend using the standard library for that:
http://www.cplusplus.com/reference/array/array/size/
But you can also do:
sizeof( givenDataPoints ) / sizeof( givenDataPoints[ 0 ] );
But you are going to get 20 because you told the compiler to allocate space for 20 elements.
You need to keep track of what is considered to be an empty element.
Here is a similar question: Find the count of elements in array in C++
I hope it helps.

Accessing values from a two dimensional initialized array

int a[][30]={{2, 16},{4, 8},{5, 16, 21},{2,6,3,5,6}};
Since the size of the second dimension is varying. If I want to access something like for a particular value of i(first dimension), access all j values(2nd dimension), how do I write that statement?
What I thought was:
for(int j=0;j<30;j++)
a[i][j]=some operation;
but its unnecessarily looping till 30 which is the max value. What's the efficient way to do it?
Thanks.
The compiler does not keep any information about how many values were in the braced initializer. Instead, it fills the "missing" values with zeros.
So these two are equivalent:
int a[][4] = {{2, 16},{4, 8, 5}};
int a[][4] = {{2, 16, 0, 0}, {4, 8, 5, 0}};
If you know that none of the "actual" data elements are zero, you can stop your loop when you find a zero element. Otherwise, you'll need to set up the data differently.
The size of both dimensions is fixed. The outer dimension has size 4 and the inner has size 30.
If you iterate over the inner dimension, then you will print lots of zeros, as that is what you initialize the remaining integers that aren't explicitly initialized to.
You seem to want this:
std::vector<int> a[] = {
boost::list_of(2)(16),
boost::list_of(4)(8),
boost::list_of(5)(16)(21),
boost::list_of(2)(6)(3)(5)(6)
};