sizeof() a vector - c++

I have a vector<set<char> > data structure (transactions database) and I want to know the size of it. When I use sizeof() with each set<char> the size is 24 in spite of the set contains 3, 4 or 5 chars. Later, when I use sizeof() with the vector<set<char> > the size is 12... I suppose this is not the way to know the size of a data structure. Any help?
Thanks.

You want vector::size() and set::size().
Assuming v is your vector, do this:
size_t size = 0;
for (vector<set<char> >::const_iterator cit = v.begin(); cit != v.end(); ++cit) {
size += cit->size();
}
sizeof() is giving you the in-memory size of the object/type it is applied to, in multiples of sizeof(char) (usually one byte). If you want to know the in-memory size of the container and its elements, you could do this:
sizeof(v) + sizeof(T) * v.capacity(); // where T is the element type

sizeof returns size of object itself. if it contains pointer to array for example it will not count size of array, it will count only size of pointer (4 on 32 bits) for vector use .size

Vector is implemented using internal pointers to the actual storage. Hence sizeof() will always return the same result which does not include the data storage itself. Try using the vector::size() method instead. This will return the number of elements in the vector.

sizeof() is computed at compile time, so there is no way it can tell you how many elements it has inside.
Use the size() method of the vector object.

vector in STL is a class template, when you give template parameter inside <SomeType> following vector, C++ compiler generated code for a class of type SomeType. So when you populate the vector using push_back, you are actually inserting another object of SomeType so when you request .size() from the compiler it gives you the number of SomeType objects inserted by you.
Hope that helps!

Use vector::size() member function to find out number of items in the vector. Hint - they are allocated on the free store.

Related

Is there a possible way to set a c++ array size to the return value of a function

I'm pretty new to C++ so please bear with me:
I am looking to set an array's size to the output of a function, for example:
//this is not the actual function, (go figure)
int getSizeInt(int size)
{
return size;
}
int main()
{
char charArray[getSizeInt(6)]; // Error: *function call must have a constant value in a constant expression*
return 0;
}
This may not be possible, I honestly don't know. I googled the issue and have been tinkering with different ways of initializing an array, but upto to no avail.
Is there a possible way to set a c++ array size to the return value of a function
Yes.
The size of an array variable must be compile time constant. A function call is a constant expression if the function is constexpr and its arguments themselves are constant expressions.
Your function does not satisfy those constraints, so its return value cannot be used as the size of an array variable.
It however can be used as the size of a dynamic array. Simplest way to create a dynamic array is to use std::vector (std::string may be considered instead if your intention is to represent text):
std::vector<char> charArray(getSizeInt(6));
Array sizes in C++ must be constant at compile-time, so the answer is sort of.
If your function is constexpr and called as part of a constant expression, then it can be used to statically set the size of the array. For example:
constexpr std::size_t square(std::size_t n) { return n * n; }
int my_array[compute_size(2)]; // array of 4 integers
However, this only works if you know all the data up-front at compile-time. If you are working with runtime values, such as things coming from files or from a user, then this will not work -- and you will have to resort to some other form of dynamic memory to handle this. In C++, generally this would be handled by a container such as a std::vector:
std::size_t compute_size() { /* some computation based on runtime */ }
// ...
auto vec = std::vector<int>{};
vec.reserve(compute_size()); // reserve the size up-front
vec.push_back( ... ); // push_back or emplace_back any data you need
If you reserve the size up front, you are able to avoid reallocation costs from push_back/emplace_back, provided you don't exceed the capacity.
Alternatively, you can initialize a vector of entries by doing either:
auto vec = std::vector<T>{};
vec.resize(N);
or
auto vec = std::vector<T>(N);
The difference here is that reserve only changes the capacity, which means you can't actually index up to N until you insert the elements -- whereas resize or vector<T>(N) will zero-initialize (fundamental types like ints) or default-construct (aggregate/class types) N instances immediately, which allows indexing.
Generally, reserve + push_back is better unless you know you want default-constructed / zero values.

How to retrieve the size of this array?

I'm using IMidiQueue to queue/add IMidiMsg objects to my IMidiQueue mMIDICreated;
At some times, I'd like to retrieve the number of items I've added on it. I've tried this:
char buffer[50];
sprintf(buffer, "size %d\n", sizeof(mMIDICreated) / sizeof(IMidiMsg));
OutputDebugString(buffer);
but after adding 8 items:
for (int i = 0; i < 4; i++) {
IMidiMsg* one = new IMidiMsg;
// ...
mMIDICreated.Add(one);
IMidiMsg* two = new IMidiMsg;
// ...
mMIDICreated.Add(two);
}
it returns 2, not 8. Where am I wrong?
sizeof will return the size of the object or type itself, it's a constant and is evaluated at compile-time, has nothing to do with the number of items which could be known only at run-time.
You should use IMidiQueue::ToDo:
Returns the number of MIDI messages in the queue.
Assuming that mMIDICreated is a pointer, doing sizeof on a pointer returns the size of the actual pointer and not what it points to. Also note that when passing an array to a function, it decays to a pointer to its first element.
If a function needs the number of elements in an array, you need to pass that along to the function as an argument.
An alternate solution, and one that I recommend over using plain arrays/pointers, is to use std::array (for arrays that are known at time of compilation) and std::vector for "run-time" or dynamic arrays.
Looking at your link:
class IMidiQueue
{
...
IMidiMsg* mBuf;
}
The buffer that stores the elements is not taken into the size returned by sizeof(). Only the size of the pointer itself.
However, there is also a method int GetSize() that could be useful to you.

Implementation defined to use a reserved vector without resizing it?

Is it implementation defined to use a reserved vector without resizing it?
By that I mean:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
std::vector<unsigned int> foo;
foo.reserve(1024);
foo[0] = 10;
std::cout<<foo[0];
return 0;
}
In the above, I reserve a good amount of space and I assigned a value to one of the indices in that space. However, I did not call push_back which "resizes" the vector and gives it a default value for each element (which I'm trying to avoid). So in this foo.size() is 0 while foo.capacity() is 1024.
So is this valid code or is it implementation defined? Seeing as I'm assigning to a vector with "0" size. It works but I'm not sure if it's a good idea..
The reason I'm trying to avoid the default value is because for large allocations, I don't need it "zero-ing" out each index as I will decide when I want to write to it or not. I'd use a raw pointer but the lodepng API accepts only a vector for decoding from file.
std::vector::reserve just reserves memory, so the next push_back does not have to allocate memory. It does not change the size of the vector.
If you want a vector with an initial size of 1024 elements, you can use the constructor to do that:
std::vector<unsigned int> foo(1024);
Note that if you create a vector with an initial size of e.g. 1024 elements, if you then do push_back you add an element, so the size of the vector increases to 1025 elements.
It is illegal, regardless of the type of item in the container or what seems to happen on a particular compiler. From 23.1.1/12 (Table 68) we learn that operator[] behaves like *(a.begin() + n). Since you haven't added any items to the container this is the same as accessing an iterator past end() which is undefined.

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().

Filling a vector with out-of-order data in C++

I'd like to fill a vector with a (known at runtime) quantity of data, but the elements arrive in (index, value) pairs rather than in the original order. These indices are guaranteed to be unique (each index from 0 to n-1 appears exactly once) so I'd like to store them as follows:
vector<Foo> myVector;
myVector.reserve(n); //total size of data is known
myVector[i_0] = v_0; //data v_0 goes at index i_0 (not necessarily 0)
...
myVector[i_n_minus_1] = v_n_minus_1;
This seems to work fine for the most part; at the end of the code, all n elements are in their proper places in the vector. However, some of the vector functions don't quite work as intended:
...
cout << myVector.size(); //prints 0, not n!
It's important to me that functions like size() still work--I may want to check for example, if all the elements were actually inserted successfully by checking if size() == n. Am I initializing the vector wrong, and if so, how should I approach this otherwise?
myVector.reserve(n) just tells the vector to allocate enough storage for n elements, so that when you push_back new elements into the vector, the vector won't have to continually reallocate more storage -- it may have to do this more than once, because it doesn't know in advance how many elements you will insert. In other words you're helping out the vector implementation by telling it something it wouldn't otherwise know, and allowing it to be more efficient.
But reserve doesn't actually make the vector be n long. The vector is empty, and in fact statements like myVector[0] = something are illegal, because the vector is of size 0: on my implementation I get an assertion failure, "vector subscript out of range". This is on Visual C++ 2012, but I think that gcc is similar.
To create a vector of the required length simply do
vector<Foo> myVector(n);
and forget about the reserve.
(As noted in the comment you an also call resize to set the vector size, but in your case it's simpler to pass the size as the constructor parameter.)
You need to call myVector.resize(n) to set (change) the size of the vector. calling reserve doesn't actually resize the vector, it just makes it so you can later resize without reallocating memory. Writing past the end of the vector (as you are doing here -- the vector size is still 0 when you write to it) is undefined behavior.