I need to make a generic function which will allocate an array that has same elements as vector in the main function.
This generic function should accept pointers/iterators to the beginning and end of the vector.
#include <iostream>
#include <new>
#include <vector>
template <typename type>
type *MakeArray(type::iterator start, type::iterator after_end) {
int n = 0;
while (start < after_end) {
start++;
n++;
}
start -= n;
type *arr = nullptr;
arr = new type[n];
throw std::bad_alloc("Not enough memory!");
while (start < after_end) {
*arr = *start;
start++;
arr++;
}
delete[] arr;
arr-=n;
return arr;
}
int main() {
int n=5;
std::vector<double>a{1,2,3,4,5};
double *arr = nullptr;
try {
arr = MakeArray(a.begin(),a.end());
} catch (std::bad_alloc e) {
std::cout << "Exception: " << e.what();
}
delete[] arr;
return 0;
}
ERRORS:
line 5:
expected ‘)’ before ‘after_end’
expected ‘;’ before ‘{’ token
line 30:
missing template arguments before ‘(’ token
I don't see any reason why should I get these errors. Could you help me to fix my code? Iterators and dynamic allocation are new to me.
You can use the iterator type itself as the template arguments and then extract the underlying type of the contained elements in the function.
Also, you shouldn't be using delete[] arr;
in your function because: (a) at that point, it no longer points to the memory allocated by the new
call; (b) if you do, you won't be able to use it in the calling module.
There are also some significant other simplifications and improvements you can make to your function, which I have shown in the below code:
template <typename it_type>
auto* MakeArray(it_type start, it_type after_end)
{
using basetype = typename std::decay< decltype(*start) >::type; // Type of contained objects
size_t size = static_cast<size_t>(std::distance(start, after_end)); // Quick calculation of size
basetype* arr = new basetype[size]; // This will automatically throw (bad_alloc) if it fails
std::copy(start, after_end, arr); // Quicker/easier way to do the data copy
return arr;
}