Is there any built in method in c++ to findout length of an array? - c++

like array.length in java is there any built in method in c++ to findout size of an array?
I know about length(). but it only works for strings only ...
And i tried this ...
int a[10];
a[0]=1;
a[1]=2;
print(sizeof(a)/size(a[0]))
but it gives output as 10 but is there a way getting only 2 as output

If you're using C++, don't use arrays, use std::vector instead (especially if you need the count of currently held items, not the container's capacity). Then you can write:
std::vector<int> vec;
vec.push_back(1);
vec.push_back(2);
printf("%d\n", vec.size());

int a[10];
declares an array of 10 ints; sure, you're only initialising the first two, but the other 8 are still there, they're just (probably) filled with junk at the moment.
To do what you want, you should use a std::vector instead. You can then do this:
std::vector<int> a;
a.push_back(1);
a.push_back(2);
std::cout << a.size() << std::endl; // prints 2

Arrays in C/C++ do not store their lengths in memory, so it is impossible to find their size purely given a pointer to an array. Any code using arrays in those languages relies on a constant known size, or a separate variable being passed around that specifies their size.
In an array of 10 ints, when it is declared, memory is allocated for 10 int values. even if you initialize just two, the rest of it contains some junk values and the memory remains allocated.
If you want the used size, your best bet is to use std::vector.

if you want to know the number of elements in an array you can do this
int array[3] = {0, 1, 2};
int arraylength = sizeof(array)/ sizeof(*array);

Sure. It's name is vector::size. It doesn't apply to C-style arrays, only to std::vector. Note that Java's Array class is also not a C-style array.

Related

Is it possible to initialize a vector of strings from an array? If so, how?

So for example, on GeeksForGeeks.org, contributing user "Kartik" offers the following example for initializing a vector of integers:
// CPP program to initialize a vector from
// an array.
#include <bits/stdc++.h>
using namespace std;
int main()
{
int arr[] = { 10, 20, 30 };
int n = sizeof(arr) / sizeof(arr[0]);
vector<int> vect(arr, arr + n);
for (int x : vect)
cout << x << " ";
return 0;
}
If I understand what I'm reading correctly, sizeof(arr) is some number (which I assume is the length of the array arr; i.e. 3, please correct me if I'm wrong) divided by sizeof(arr[0]) (which I assume to be 1) -- basically just being a roundabout way of saying 3/1 = 3.
At this point, vector<int> vect(arr, arr + n) appears to be a vector of size 3, with all values initialized to arr + n (which I'm assuming is a way of saying "use the 3 items from arr to instantiate; again, please correct me if I'm wrong).
Through whatever sorcery, the output is 10 20 30.
Now, regardless of whether or not any of my above rambling is coherent or even remotely correct, my main question is this: can the same technique be used to instantiate some example vector<string> stringVector such that it would iterate through strings designated by some example string stringArray[] = { "wordA", "wordB", "wordC" }? Because, as I understand it, strings have no numeric values, so I imagine it would be difficult to just say vector<string> stringVector(stringArray, stringArray + n) without encountering some funky junk. So if it is possible, how would one go about doing it?
As a rider, why, or in what type of instance, would anyone want to do this for a vector? Does instantiating it from an array (which as I understand it has constant size) defeat the purpose of the vector?
Just as a disclaimer, I'm new to C++ and a lot of the object-oriented syntax involving stuff like std::vector<_Ty, _Alloc>::vector...etc. makes absolutely no sense to me, so I may need that explained in an answer.
To whoever reads this, thank you for taking the time. I hope you're having a good day!
Clarifications:
sizeof(arr): returns the size in bytes of the array, which is 12 because it has 3 ints, and each int in most implementations has a size of 4 bytes, so 3 bytes x 4 = 12 bytes.
sizeof(arr[0]): returns the size in bytes of the first element of the array, which is 4 because it is an int array.
vector<int> vect(arr, arr + n): the vector class has multiple constructors. Here we are not using the constructor you are thinking of. We are using a constructor that takes begin and end iterators for a range of elements, making a copy of those elements. Pointers can be used as iterators, where in this case arr is the begin iterator and arr + n is the end iterator.
Note: int* + int returns int*.
Note: We should also consider that the "end" of an array is a pointer to the next space after the last item in the array, and the constructor will copy all the items except the item past the end.
Answer:
Yes, remember that here, the constructor is taking iterators, not any item of the array, so we can do it easily like this with little changes:
#include <bits/stdc++.h>
using namespace std;
int main()
{
// changed int to string and the array values
string arr[] = { "one", "two", "three" };
int n = sizeof(arr) / sizeof(arr[0]);
// changed int to string
vector<string> vect(arr, arr + n);
// changed int to string
for (string x : vect)
cout << x << " ";
return 0;
}
sizeof(arr)
sizeof gets the size of an object in bytes. The size of an object is the total number of bytes required by the object. Note that I'm using "object" in the C++ context, not the OOP context (an instance of a class).
The size of an object of a given type is always the same. A std::string containing "a" is the same size as a string containing the unabridged text of War and Peace. Any object that appears to have a variable size really contains a reference to variable length data stored elsewhere. In the case of std::string at its most basic, it is a pointer to a dynamically allocated array and an integer keeping track of how much of the dynamically allocated array is actually in use by the string. std::vector is similar, typically it's a pointer to the start of its data, a pointer to the end of its data, and a pointer to the first empty position in the data. No matter how big the vector is, sizeof(vector) will return the size of the pointers, any other book-keeping variables in the vector implementation, and any padding needed to guarantee correct memory alignment.
This means every item in an array is always the same size and thus the same distance from one another.
Through whatever sorcery...
The above means that the total size of the array divided by the size of one element in the array, sizeof(arr) / sizeof(arr[0]), will always provide the number of elements in the array. It doesn't matter what the array contains, numerical or otherwise. There are of course prettier ways like
template <class T, size_t N>
size_t getsize (const T (&array)[N])
{
return N;
}
and later
size_t n = getsize(arr);
As a rider, why, or in what type of instance, would anyone want to do this for a vector?
In the old days one could not directly construct a vector pre-loaded with data. No one wants to write some arbitrary number of lines of push_back to pound all the values in manually, It's boring as hell, a programmer almost always has better things to do, and the odds of injecting an error are too high. But you could nicely and easily format an array and feed the array into the vector, if you needed a vector at all. A lot of the time you could live off the array by itself because the contents were unchanging or at worst would only be shuffled around.
But if the number of contents could change, it could be time for a vector. If you're going to add items and you don't know the upper limit, it's time for vector. If you're calling into an API that requires a vector, it's time for a vector.
I can't speak for everybody, but I'm going to assume that like me a lot of people would have loved to have that easy-peasy array-style initialization for vectors, lists, maps, and the rest of the usual gang.
We were forced to write programs that generated the appropriate code to fill up the vector or define an array and copy the array into the vector much like the above example.
In C++11 we got our wish with std::initialzer_list and a variety of new initialization options1 that allowed
vector<string> vect{"abc","def","ghi"};
eliminating most cases where you would find yourself copying an array into a library container. And the masses rejoiced.
This coincided with a number of tools like std::size, std::begin and std::end to make converting an array into a vector a cakewalk. Assuming you don't pass the array into a function first.
1 Unfortunately the list of initialization options can get a lil' bewildering
Yes, you can do so - you just need to define something that the constructor for String will take (which is a 'const char')
const char * arr[] = { "abc","def","ghi" };
int n = sizeof(arr) / sizeof(arr[0]);
vector<string> vect(arr, arr + n);
for (string &x : vect)
cout << x << " ";
What this is effectively doing is creating the vector from two iterators (a pointer is, loosely, an iterator):
https://en.cppreference.com/w/cpp/container/vector/vector
Constructs the container with the contents of the range [first, last).
This constructor has the same effect as vector(static_cast<size_type>(first), static_cast<value_type>(last), a) if InputIt is an integral type.
And as #MartinYork pointed out, it's much more readable to use the C++ syntax:
const char * arr[] = { "abc","def","ghi" };
vector<string> vect(std::begin(arr), std::end(arr));
So if it is possible, how would one go about doing it?
Simply use vector constructor number 5, which accepts iterators to start and end of range
Constructs the container with the contents of the range [first,
last).
#include <iostream>
#include <vector>
#include <string>
int main()
{
std::string arr[] = { "wordA", "wordB", "wordC" };
std::vector<std::string> v {std::begin(arr), std::end(arr)};
for (auto& str : v)
std::cout << str << "\n";
return 0;
}
Here's how you'd do it. Note that it's a tad awkward to get the length of the array, but that's just because arrays don't carry that information around with them (use a vector!).
#include<string>
#include<vector>
#include<iterator>
#include<iostream>
int main()
{
std::string arr[] = {"abc", "def", "ghi"};
std::vector<std::string> tmp;
std::copy(arr, arr + sizeof(arr)/sizeof(arr[0]), std::back_inserter(tmp));
for(auto str : tmp) {
std::cout<<str<<"\n";
}
}
Update: Yes good point about using std::begin and std::end for the array.

can we check the size of dynamic array on runtime

I create an array of size int arr[50]; but I will insert value in it during compile time , like my solution will insert 10 values in it after performing some function (different amount of values can come) , Now in second part of my program I have to loop through the array like it should iterate <= total values of array like in int arr[50] my program save 10 values , it should iterate to it only 10 times but how I can get that there is only 10 values in that array.
arr[50]=sum;
for (int ut=0; ut<=arr[100].length();ut++)
Though i know ut<=arr[100].length() is wrong , but its just assumption , that function will work if I solve condition in this way.
Edit:
I know we can use vector , but I am just looking that type of thing using array.
Thanks for response
First of all, the array you show is not a "Dynamic Array". It's created on the stack; it's an automatic variable.
For your particular example, you could do something like this:
int arr[50];
// ... some code
int elem_count = sizeof(arr) / sizeof(arr[0]);
In that case, the sizeof(arr) part will return the total size of the array in bytes, and sizeof(arr[0]) would return the size of a single element in bytes.
However, C-style arrays come with their share of problems. I'm not saying never use them, but keep in mind that, for example, they adjust to pointers when passed as function arguments, and the sizeof solution above will give you an answer other than the one you are looking for, because it would return sizeof(int*).
As for actual dynamically allocated arrays (where all what you have is the pointer to that array), declared as follows:
int *arr = new int[50];
// ... do some stuff
delete [] arr;
then sizeof(arr) will also give you the size of an int* in bytes, which is not the size you are looking for.
So, as the comments suggested, if you are looking for a convenient random access container where you want to conveniently and cheaply keep track of the size, use a std::vector, or even a std::array.
UPDATE
To use a std::array to produce equivalent code to that in your question:
std::array<int, 50> arr;
and then use it like a normal array. Keep in mind that doing something like arr[100] will not do any bounds checking, but at least you can obtain the array's size with arr.size().

How to make a number returned from a function be used for defining no of elements in an array?

I am using Opencv/c++.
I get the number of frames in a video using the function
int noOfFrames = cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_COUNT );
I have also declared an array int Entropy[noOfFrames];. But as the variable noOfFrames is non-const, it gives an error.
I even used const_cast for this but still it gives an error. I want the length of the array to be equal to the no of frames of the video.
How can I do it ???
You can't declare a static array with a dynamic size. You need a dynamic array:
int* Entropy = new Entropy[noOfFrames];
// use here, same as array
delete[] Entropy;
But using a vector is just easier:
std::vector<int> Entropy(noOfFrames);
// use here, same as array and more
// no need to clean up, std::vector<int> cleans itself up
In C++, you cannot do that because the size of a c-style array should be a compile-time constant1.
Anyway, you have a superior alternative : use std::vector
std::vector<int> Entropy(noOfFrames);
Even if you have compile-time constant, I would not suggest you to use int arr[size] which is c-style array. Instead I would suggest you to use std::array<int,size> arr; which is again far superior solution.

Pointer to an array get size C++

int * a;
a = new int[10];
cout << sizeof(a)/sizeof(int);
if i would use a normal array the answer would be 10,
alas, the lucky number printed was 1, because sizeof(int) is 4 and iszeof(*int) is 4 too. How do i owercome this? In my case keeping size in memory is a complicated option. How do i get size using code?
My best guess would be to iterate through an array and search for it's end, and the end is 0, right? Any suggestions?
--edit
well, what i fear about vectors is that it will reallocate while pushing back, well you got the point, i can jus allocate the memory. Hoever i cant change the stucture, the whole code is releevant. Thanks for the answers, i see there's no way around, so ill just look for a way to store the size in memory.
what i asked whas not what kind of structure to use.
Simple.
Use std::vector<int> Or std::array<int, N> (where N is a compile-time constant).
If you know the size of your array at compile time, and it doens't need to grow at runtime, then use std::array. Else use std::vector.
These are called sequence-container classes which define a member function called size() which returns the number of elements in the container. You can use that whenever you need to know the size. :-)
Read the documentation:
std::array with example
std::vector with example
When you use std::vector, you should consider using reserve() if you've some vague idea of the number of elements the container is going to hold. That will give you performance benefit.
If you worry about performance of std::vector vs raw-arrays, then read the accepted answer here:
Is std::vector so much slower than plain arrays?
It explains why the code in the question is slow, which has nothing to do with std::vector itself, rather its incorrect usage.
If you cannot use either of them, and are forced to use int*, then I would suggest these two alternatives. Choose whatever suits your need.
struct array
{
int *elements; //elements
size_t size; //number of elements
};
That is self-explanatory.
The second one is this: allocate memory for one more element and store the size in the first element as:
int N = howManyElements();
int *array = int new[N+1]; //allocate memory for size storage also!
array[0] = N; //store N in the first element!
//your code : iterate i=1 to i<=N
//must delete it once done
delete []array;
sizeof(a) is going to be the size of the pointer, not the size of the allocated array.
There is no way to get the size of the array after you've allocated it. The sizeof operator has to be able to be evaluated at compile time.
How would the compiler know how big the array was in this function?
void foo(int size)
{
int * a;
a = new int[size];
cout << sizeof(a)/sizeof(int);
delete[] a;
}
It couldn't. So it's not possible for the sizeof operator to return the size of an allocated array. And, in fact, there is no reliable way to get the size of an array you've allocated with new. Let me repeat this there is no reliable way to get the size of an array you've allocated with new. You have to store the size someplace.
Luckily, this problem has already been solved for you, and it's guaranteed to be there in any implementation of C++. If you want a nice array that stores the size along with the array, use ::std::vector. Particularly if you're using new to allocate your array.
#include <vector>
void foo(int size)
{
::std::vector<int> a(size);
cout << a.size();
}
There you go. Notice how you no longer have to remember to delete it. As a further note, using ::std::vector in this way has no performance penalty over using new in the way you were using it.
If you are unable to use std::vector and std::array as you have stated, than your only remaning option is to keep track of the size of the array yourself.
I still suspect that your reasons for avoiding std::vector are misguided. Even for performance monitoring software, intelligent uses of vector are reasonable. If you are concerned about resizing you can preallocate the vector to be reasonably large.

determining the size of an array

What is the appropriate function that shows how many are there in an array?
int a[10];
a[0] = 1;
a[1] = 3;
So I want something that shows size of a = 2.
There is no way to do this with raw arrays.
Consider a container class instead, such as std::vector:
std::vector<int> a;
a.push_back(1);
a.push_back(3);
std::cout << a.size() << "\n"; // Displays "2"
Sounds like you need a dynamically resizable array:
std::vector<int> a;
a.push_back(1);
a.push_back(3);
std::cout << a.size(); // 2
This array has 10 elements. You just happened to assign two of them but this doesn't change the size of the areay. If you want simething to keep track of the elements you set use std::vector<int> and push_back():
std::vector<int> array;
array.push_back(1);
array.push_back(3);
int size = array.size();
Oil Charlesworth seems to be right. The reason this is true is that when compiled a certain amount of memory is set aside (allocated) for that array no matter if it contains data or not. Therefore using a command like sizeof(a) will always yield the same result. It will return the amount of bytes allocated for your array. In this case the array is 40 bytes which makes sense because usually ints are 4 bytes long * length of the array (10) = 40.
This can differ from PC to PC though, at least, that's what I read in a tutorial a while back, the allocated size for each variable type seems to differ somewhat from PC to PC (or OS to OS).
ItÅ› not much help, I know, but now you at least know why you can't do it with raw arrays.