initizlize an array from a vector - c++

It is possible to initialise a vector from an array holding elements with the same type as vector, such as
double a[] ={ somevalues };
std::vector<double> vec(a, a+dimension)
I was wondering whether the other way around is possible or not without an explicit loop? Is that possible to initialise an array from a vector with a short cut like the one above, I guess not but let me ask ...

No, it is not possible to do it at initialization, but you can use one algorithm from the STL:
std::vector<int> v = create_vector();
int array[100];
assert( v.size() >= 100 );
std::copy( v.begin(), v.begin()+100, array );
Or alternatively:
std::copy_n( v.begin(), 100, array );
The assert is to ensure that you don't go beyond the size of the vector (which would cause undefined behavior), and limiting the copies (the 100 in the expressions) so that you don't overflow the array either.

Yes you can initialize a vector from an array of the same type:
int a[] = {16,2,77,29};
vector<int> v (a, a + sizeof(a) / sizeof(*a) );
You can use std::copy to copy the vector to an array
copy( v.begin(), v.begin()+MAX_SIZE, a); // or v.end() if a is large enough to hold the whole vector

Alternative to what was answered in this question is to have a pointer associated with vector's first variable (vector lays in contiguous memory):
assume following vector:
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
our pointer:
int *num_arr = &v[0];
Advantages - instead of doubling the amount of memory by creating a new dynamic array of vec.capacity() size, you have a pointer to vec's first element, with which you can do the same thing as normal array, except that you have to pass the size, but anyway you can't estimate the size of dynamically allocated array through sizeof(array) / sizeof(*array).
calling the function:
print_out_array(&v[0], v.size());
you can have a function that prints out the "array":
print_out_array(const int* array, std::size_t size){
cout << "Printing out array:" << endl;
for (int i=0; i != size; ++i){
cout << "i: " << i << ", value: " << array[i] << endl;
}
}
See, in that function array[i] works just like array, no copies involved, no overhead in copying, no new memory is allocated - all good! :)
But you have to be careful if the vector is empty though. If v.size() is zero then &v[0] attempts to produce a pointer to something that doesn't exist - undefined behaviour.
Safer way:
if(!v.empty()){
print_array(&v[0],v.size());
}
But be careful with strings though... they are completely different beasts...
To get full information about that matter have a look in Scott Meyer's Effective STL Item 16. Know how to pass vector and string data to legacy APIs.

No. You can use
double a[] = { v[0], v[1], ... };
but easier you cannot get.

Related

Why does sizeof(ar)/ sizeof(ar[0]) not work properly on a vector when passed to a function?

I'm trying to get to know c++ better and came across this confusion.
int simpleArraySum(const vector<int> ar) {
int n=sizeof(ar)/sizeof(ar[0]);
int sum=0;
for (int i=0; i<n; i++){
sum+=ar[i];
}
return sum;
}
When I passed a vector of 10 elements the result was lower than expected. I checked that n=6 unlike when I use size() which gives n=10. My confusion comes since the way the code is written works normally in main with sizeof(ar)/sizeof(ar[0]).
Using the "sizeof trick" have never worked on a std::vector.
The size of a std::vector object is the size of the std::vector object itself, not the possible data handled by the vector.
If you want to get the number of elements from a std::vector object, use the size member function.
The "sizeof trick" only works on actual arrays, like e.g.
int array[10];
std::cout << sizeof(array) / sizeof(array[0]) << '\n'; // Will print 10
As for the problem you try to solve with your function, there are much better ways to handle it.
First you could iterate using the size (like you do now)
for (size_t i = 0; i < ar.size(); ++i)
sum += ar[i];
Then you could iterate using iterators
for (auto i = ar.begin(); i != ar.end(); ++i)
sum += *i;
Then you have range-based for loops
for (auto value : ar)
sum += value;
Lastly you can use a standard algorithm function like std::accumulate
int simpleArraySum(std::vector<int> const& ar)
{
return std::accumulate(begin(ar), end(ar), 0);
}
Why does sizeof(ar)/ sizeof(ar[0]) not work properly on a vector ...
sizeof(ar)/ sizeof(ar[0]) is an expression that gives you the length of an array, and only an array. std::vector is not an array. std::vector is a class (template).sizeof(std::vector) is entirely unrelated to the number of elements it has i.e. its length.
The size of all types is compile time constant. std::vector's can contain a variable number of elements that is not compile time constant. Therefore the size of vector type cannot depend on the number of elements.
... when passed to a function?
It won't work when not passing into a function either.

Size of array of std::vector

I would like to check the size() or number of rows in an array of std::vector().
I have vector like
std::vector<int> vec[3];
vec.size() does not work with the above vector declaration.
As for why vec.size() does not work, it's because vec is not a vector, it's an array (of vectors), and arrays in C++ are not objects (in the OOP sense that they are not instances of a class) and therefore have no member functions.
If you want to get the result 3 when doing vec.size() then you either have to use e.g. std::array:
std::array<std::vector<int>, 3> vec;
std::cout << "vec.size() = " << vec.size() << '\n'; // Will output 3
Or if you don't have std::array then use a vector of vectors and set the size by calling the correct constructor:
std::vector<std::vector<int>> vec(3);
std::cout << "vec.size() = " << vec.size() << '\n'; // Will output 3
There's nothing inherent in std::vector<int> vec[3]; to say where the first or second indexing operation constitutes "rows" vs. "columns" - it's all a matter of your own perspective as a programmer. That said, if you consider this to have 3 rows, you can retrieve that number using...
std::extent<decltype(vec)>::value
...for which you'll need to #include <type_traits>. See here.
Anyway, std::array<> is specifically designed to provide a better, more consistent interface - and will already be familiar from std::vector:
std::array<std::vector<int>, 3> vec;
...use vec.size()...
(Consistency is particularly important if you want templated code to handle both vectors and arrays.)
Try
int Nrows = 3;
int Ncols = 4
std::vector<std::vector<int>> vec(Nrows);
for(int k=0;k<Nrows;k++)
vec[k].resize(Ncols);
...
auto Nrows = vec.size();
auto Ncols = (Nrows > 0 ? vec[0].size() : 0);
Either use sizeof(vec[0])/sizeof(vec) or sizeof(vec)/sizeof(vector<int>)

C++ iterate an array of integers whose size is unknown?

I have the following array:
int* myArray = new int[45];
If I wanted to iterate each element without knowing the actual size of the array, I would need to use a for_each?
If so, then how would you write the for_each? I was looking over the following site and reading up on for_each but can't figure out how to put this together.
http://www.cplusplus.com/reference/algorithm/for_each/
Update: A for_each is not a good choice in this case, due to the fact that the size of the array has to be known. vectors are the proper way to accomplish such task. My reason for using arrays, in this case, was for learning purposes. if this was a serious project I would move to something such as Lists/Vectors.
Note when the question was first posted, the array in question was declared as
int myArray[45];
This answer deals with that particular case.
If you have C++11 support, you can use a range based loop:
for (int& i : myArray) {
std::cout << i << "\n";
}
C++11 also provides std::begin and std::end, which you can use with a fixed size array to obtain iterators:
std::for_each(std::begin(myArray), std::end(myArray), <func>);
Another option, which works for C++03 and you are dealing with fixed size arrays, is to define a function template:
// taken a fixed size array by reference and loop over it
template <typename T, unsigned int N>
void array_for_each( T (&a)[N]) {
for (unsigned int i = 0; i < N; ++i) {
// do something with array elements
std::cout << a[i] << " ";
}
}
int main() {
int a[5];
array_for_each(a);
}
If you use MSVC (Microsoft Visual C++), you can use "for each."
for each(int i in arr) {
cout << i << ' ' << endl;
}
NOTE: This only works in the block of code the array is declared in.
If not, you can also use the new range-based for loop in the C++11 standard.
for(int i : arr) {
cout << i << ' ' << endl;
}
If you're intent upon the std::for_each:
for_each(arr,arr + 10,[] (int i) {
cout << i << ' ' << endl;
});
NOTE: This requires knowledge of the size of the array (in this example, 10).
You could use a for_each. In this case, you have allocated space for 45 elements in your array, but since it is NULL, you'd probably get a segfault if you tried to do anything. You either need to hold a value of the array, or use something like sizeof(myArray)/sizeof(myArray[0]) (which has its own problems).
Anyway, for a for_each here, if we actually had 45 elements:
std::for_each(myArray, myArray + 45, <func>);
Anyway, this is part of the reason to use vectors: .begin() and .end() reduces errors with using incorrect indexing.
You have described an array of int, not a class that implements a InputIterator, which is what the for_each is designed for, even though you can use it to iterate an array, but you need to know the size of the array to iterate it.
If you want to use for_each you need to use a vector, list, or implement a class that keeps track of the number of elements it contains. IMO it is much easier to just use a vector
If you want to just iterate your current array, assuming it is 0 terminated:
for(int *value = myArray; *value != 0; ++value)
printf("%d\n", *value);
Or, you can use indexes:
for(int index = 0; myArray[index] != 0; ++index)
printf("%d\n", myArray[index]);
IMO the pointer method is cleaner.
This code is still dangerous though, you should either keep track of the number of records in a seperate variable, or use a vector.

Vector. How to set the maximum number of elements and find the current count?

I want to create a vector with a maximum number of elements 48, and I want to know at any time the current number of elements in the vector.
I use this code:
.h
std::vector< CPPobject* >vec;
.mm
int maxCountElementInVec = 48;
vec.resize( maxCountElementInVec );
int countElement = sizeof( vec ) / sizeof( vec[0] );
printf("%d ",countElement); // return 3
<...>
vec.push_back( some_cpp_obj );
int countElement = sizeof( vec ) / sizeof( vec[0] );
if( countElement > maxCountElementInVec ) printf("Evrika");
printf("%d ",countElement); // return 3
CountElement always is 3
You cannot set the maximum number of elements.
The length however is retrieved with
int length = myVector.size();
Finding the number of elements can be achieved with the .size() method.
For setting a limit, you can create a wrapper over std::vector:
template<typename T>
class MyVector : public std::vector<T>
{
int _maxSize;
public:
void setMaxSize(int maxSize) {_maxSize = maxSize;}
void push_back(const T& element)
{
if (std::vector<T>::size() < _maxSize)
std::vector<T>::push_back(element);
else
{
//disallow - throw exception or whatever
}
}
};
Wrapper Not Good. That open the door for memory leak because std::vector have no virtual destructor.
Let leak some memory:
// Construct std::vector & MyVector
std::vector * v = dynamic_cast<std::vector *>( new MyVector() );
// Destruct only std::vector
delete v;
That's construction of MyVector without a call to it's Destructor.
Let go crazy:
MyVector * mv = new MyVector(); // Construct std::vector & MyVector
std::vector * v = dynamic_cast<std::vector *>( mv );
delete v; // Destruct only std::vector
mv.resize(74); // Usage of a partially destroy object.
That's use a partially destroy object. Let's spin the wheel of trouble!
Getting the number of elements in the vector is very simple. Just call vec.size(). You can not restrict the vector not to resize over the reserved size.
What you query is the size of the structure of vector over the size of a simple pointer. The elements of the vector are not part of this size - thus you get constant size.
I don't think sizeof on STL vectors is doing something very useful here. As pointed out by Kerrek in a comment, it does not evaluate to something that is proportional to the number of elements in the vector. Just use size() to get the current number of elements held in the vector.
You could switch to EASTL, which provides fixed_vector which is just like a vector except all memory is allocated up-front, so it can't grow to more than what you specify. It still maintains a size() tracking how many elements have been inserted, though.

How does the range-based for work for plain arrays?

In C++11 you can use a range-based for, which acts as the foreach of other languages. It works even with plain C arrays:
int numbers[] = { 1, 2, 3, 4, 5 };
for (int& n : numbers) {
n *= 2;
}
How does it know when to stop? Does it only work with static arrays that have been declared in the same scope the for is used in? How would you use this for with dynamic arrays?
It works for any expression whose type is an array. For example:
int (*arraypointer)[4] = new int[1][4]{{1, 2, 3, 4}};
for(int &n : *arraypointer)
n *= 2;
delete [] arraypointer;
For a more detailed explanation, if the type of the expression passed to the right of : is an array type, then the loop iterates from ptr to ptr + size (ptr pointing to the first element of the array, size being the element count of the array).
This is in contrast to user defined types, which work by looking up begin and end as members if you pass a class object or (if there is no members called that way) non-member functions. Those functions will yield the begin and end iterators (pointing to directly after the last element and the begin of the sequence respectively).
This question clears up why that difference exists.
I think that the most important part of this question is, how C++ knows what the size of an array is (at least I wanted to know it when I found this question).
C++ knows the size of an array, because it's a part of the array's definition - it's the type of the variable. A compiler has to know the type.
Since C++11 std::extent can be used to obtain the size of an array:
int size1{ std::extent< char[5] >::value };
std::cout << "Array size: " << size1 << std::endl;
Of course, this doesn't make much sense, because you have to explicitly provide the size in the first line, which you then obtain in the second line. But you can also use decltype and then it gets more interesting:
char v[] { 'A', 'B', 'C', 'D' };
int size2{ std::extent< decltype(v) >::value };
std::cout << "Array size: " << size2 << std::endl;
According to the latest C++ Working Draft (n3376) the ranged for statement is equivalent to the following:
{
auto && __range = range-init;
for (auto __begin = begin-expr,
__end = end-expr;
__begin != __end;
++__begin) {
for-range-declaration = *__begin;
statement
}
}
So it knows how to stop the same way a regular for loop using iterators does.
I think you may be looking for something like the following to provide a way to use the above syntax with arrays which consist of only a pointer and size (dynamic arrays):
template <typename T>
class Range
{
public:
Range(T* collection, size_t size) :
mCollection(collection), mSize(size)
{
}
T* begin() { return &mCollection[0]; }
T* end () { return &mCollection[mSize]; }
private:
T* mCollection;
size_t mSize;
};
This class template can then be used to create a range, over which you can iterate using the new ranged for syntax. I am using this to run through all animation objects in a scene which is imported using a library that only returns a pointer to an array and a size as separate values.
for ( auto pAnimation : Range<aiAnimation*>(pScene->mAnimations, pScene->mNumAnimations) )
{
// Do something with each pAnimation instance here
}
This syntax is, in my opinion, much clearer than what you would get using std::for_each or a plain for loop.
It knows when to stop because it knows the bounds of static arrays.
I'm not sure what do you mean by "dynamic arrays", in any case, if not iterating over static arrays, informally, the compiler looks up the names begin and end in the scope of the class of the object you iterate over, or looks up for begin(range) and end(range) using argument-dependent lookup and uses them as iterators.
For more information, in the C++11 standard (or public draft thereof), "6.5.4 The range-based for statement", pg.145
How does the range-based for work for plain arrays?
Is that to read as, "Tell me what a ranged-for does (with arrays)?"
I'll answer assuming that - Take the following example using nested arrays:
int ia[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
for (auto &pl : ia)
Text version:
ia is an array of arrays ("nested array"), containing [3] arrays, with each containing [4] values. The above example loops through ia by it's primary 'range' ([3]), and therefore loops [3] times. Each loop produces one of ia's [3] primary values starting from the first and ending with the last - An array containing [4] values.
First loop: pl equals {1,2,3,4} - An array
Second loop: pl equals {5,6,7,8} - An array
Third loop: pl equals {9,10,11,12} - An array
Before we explain the process, here are some friendly reminders about arrays:
Arrays are interpreted as pointers to their first value - Using an array without any iteration returns the address of the first value
pl must be a reference because we cannot copy arrays
With arrays, when you add a number to the array object itself, it advances forward that many times and 'points' to the equivalent entry - If n is the number in question, then ia[n] is the same as *(ia+n) (We're dereferencing the address that's n entries forward), and ia+n is the same as &ia[n] (We're getting the address of the that entry in the array).
Here's what's going on:
On each loop, pl is set as a reference to ia[n], with n equaling the current loop count starting from 0. So, pl is ia[0] on the first round, on the second it's ia[1], and so on. It retrieves the value via iteration.
The loop goes on so long as ia+n is less than end(ia).
...And that's about it.
It's really just a simplified way to write this:
int ia[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
for (int n = 0; n != 3; ++n)
auto &pl = ia[n];
If your array isn't nested, then this process becomes a bit simpler in that a reference is not needed, because the iterated value isn't an array but rather a 'normal' value:
int ib[3] = {1,2,3};
// short
for (auto pl : ib)
cout << pl;
// long
for (int n = 0; n != 3; ++n)
cout << ib[n];
Some additional information
What if we didn't want to use the auto keyword when creating pl? What would that look like?
In the following example, pl refers to an array of four integers. On each loop pl is given the value ia[n]:
int ia[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
for (int (&pl)[4] : ia)
And... That's how it works, with additional information to brush away any confusion. It's just a 'shorthand' for loop that automatically counts for you, but lacks a way to retrieve the current loop without doing it manually.
Some sample code to demonstrate the difference between arrays on Stack vs arrays on Heap
/**
* Question: Can we use range based for built-in arrays
* Answer: Maybe
* 1) Yes, when array is on the Stack
* 2) No, when array is the Heap
* 3) Yes, When the array is on the Stack,
* but the array elements are on the HEAP
*/
void testStackHeapArrays() {
int Size = 5;
Square StackSquares[Size]; // 5 Square's on Stack
int StackInts[Size]; // 5 int's on Stack
// auto is Square, passed as constant reference
for (const auto &Sq : StackSquares)
cout << "StackSquare has length " << Sq.getLength() << endl;
// auto is int, passed as constant reference
// the int values are whatever is in memory!!!
for (const auto &I : StackInts)
cout << "StackInts value is " << I << endl;
// Better version would be: auto HeapSquares = new Square[Size];
Square *HeapSquares = new Square[Size]; // 5 Square's on Heap
int *HeapInts = new int[Size]; // 5 int's on Heap
// does not compile,
// *HeapSquares is a pointer to the start of a memory location,
// compiler cannot know how many Square's it has
// for (auto &Sq : HeapSquares)
// cout << "HeapSquare has length " << Sq.getLength() << endl;
// does not compile, same reason as above
// for (const auto &I : HeapInts)
// cout << "HeapInts value is " << I << endl;
// Create 3 Square objects on the Heap
// Create an array of size-3 on the Stack with Square pointers
// size of array is known to compiler
Square *HeapSquares2[]{new Square(23), new Square(57), new Square(99)};
// auto is Square*, passed as constant reference
for (const auto &Sq : HeapSquares2)
cout << "HeapSquare2 has length " << Sq->getLength() << endl;
// Create 3 int objects on the Heap
// Create an array of size-3 on the Stack with int pointers
// size of array is known to compiler
int *HeapInts2[]{new int(23), new int(57), new int(99)};
// auto is int*, passed as constant reference
for (const auto &I : HeapInts2)
cout << "HeapInts2 has value " << *I << endl;
delete[] HeapSquares;
delete[] HeapInts;
for (const auto &Sq : HeapSquares2) delete Sq;
for (const auto &I : HeapInts2) delete I;
// cannot delete HeapSquares2 or HeapInts2 since those arrays are on Stack
}