In C, I do
int (*ptr)[100];
ptr=malloc(sizeof *ptr); // this is the easy/error proof way of doing it
Is there an error proof C++ way of doing the same with new
operator
int (*ptr)[100];
ptr=new __what_comes_here?
In C, I do
int (*ptr)[100];
ptr=malloc(sizeof *ptr); // this is the easy/error proof way of doing it
Is there an error proof C++ way of doing the same with new
operator
int (*ptr)[100];
ptr=new __what_comes_here?
int (*ptr)[100];
means ptr
is a pointer, which should hold an address of an array of 100 integers. In other words, technically if you have, something like:
int arr[100]; // automatic (compile time allocated) object of 100 integers
Then you may want to use:
ptr = &arr;
But that is not the case here. So you can do with a simple pointer. If you want to go dynamic then you either go for malloc
equivalent:
int *p = new int[100]; // do `delete[] p` later to reclaim memory
Note that, p
is a simple pointer, which holds the address of the first integer of the dynamically allocated array.
But better practice is to use standard container to avoid any memory management:
std::vector<int> v(100);
If the size 100 is fixed then you may use:
int a[100]; // C-style
Or
std::array<int, 100> arr; // C++11 onwards
If you require new
and don't have luxury of using above facilities but still want automatic reclamation of memory then use unique_ptr
as following:
std::unique_ptr<int[]> p(new int[100]);
The way I'm showing here is obviously not a great solution, I just wanted to sort of answer the question in a unique way.
template<typename>
struct deref;
template<typename T>
struct deref<T*>
{
typedef T type;
};
int main() {
int (*ptr)[100];
ptr = new deref<decltype(ptr)>::type[1];
return 0;
}
I know that the [1]
is obviously highly suspicious but without it, the result of the new
seems to just decay to a int*
. So I think that adding it causes only the "outer" array to decay and leave the inner intact.
Also this means that you need to call delete[]
to clean it up and not cause undefined behaviour.
If you want to convince yourself that this actually allocates the necessary space and it can access it correctly you can see the output of godbolt in an example.
typedef int IntArray[100];
int main()
{
IntArray* p = new IntArray[1];
delete[] p;
return 0;
}
Note that you must deallocate thus allocated array with delete[]
.
Not quite what you asked for, but you can what you want using template type deduction.
template <typename T, std::size_t N>
void populate_ptr(T (*&ptr)[N])
{
// Its a shame the return value of new T[N] is T*, not T(*)[N]
ptr = reinterpret_cast<T(*)[N]>(new T[N]);
}
int (*ptr)[100];
populate_ptr(ptr);
// Don't forget to delete[](ptr) later!
You can't deduce templates on return values, so you can't use assignment, but passing-by-reference should be equivalent for all use-cases.
Not that this is a great way of handling this, but being able to do template type deduction against C-style arrays comes in handy from time to time..