Is there any difference between fncs: operator new and operator new[] (NOT new and new[] operators)? Except of course call syntax? I'm asking because I can allocate X number of bytes for my objs with ::operator new(sizeof(T)*numberOfObject) and then access them with array notation, so what's the big deal with ::operator new[]. Is it only syntactic sugar?
#include <new>
#include <iostream>
#include <malloc.h>
using namespace std;
struct X
{
int data_;
X(int v):data_(v){}
};
int _tmain(int argc, _TCHAR* argv[])
{
unsigned no = 10;
void* vp = ::operator new(sizeof(X) * no);
cout << "Mem reserved: " << _msize(vp) << '\n';
X* xp = static_cast<X*>(vp);
for (unsigned i = 0; i < no; ++i)
{
new (xp + i) X(i);
}
for (unsigned i = 0; i < no; ++i)
{
cout << (xp[i]).data_ << '\n';
}
for (unsigned i = 0; i < no; ++i)
{
(xp + i)->~X();
}
::operator delete(vp);
return 0;
}
new() The new operator requests for the memory allocation in heap. If the sufficient memory is available, it initializes the memory to the pointer variable and returns its address.
The new operator lets developers create an instance of a user-defined object type or of one of the built-in object types that has a constructor function.
Difference Between new and delete Operator in C++ In brief, new is an operator in C++ that allocates memory for an object or an array of objects. In contrast, delete is an operator in C++ that deallocates a block of memory previously allocated for an object created using the new operator.
An Example of allocating array elements using “new” operator is given below: int* myarray = NULL; myarray = new int[10]; Here, new operator allocates 10 continuous elements of type integer to the pointer variable myarray and returns the pointer to the first element of myarray.
These functions (operator new
etc.) are not generally intended to be called explicitly, but rather used implicitly by new
/new[]
expressions (symmetrically, operator delete
/operator delete[]
functions are invoked implicitly by delete
/delete[]
expressions). An expression that uses new
syntax for non-array type will implicitly call operator new
function, while an expression with new[]
will implicitly call operator new[]
.
The important detail here is that an array created by new[]
expression will normally be destroyed later by delete[]
expression. The latter will need to know the number of objects to destruct (if the objects have non-trivial destructors), i.e. this information has to be passed somehow from new[]
expression (when it was known) to the corresponding delete[]
expression (when it is needed). In a typical implementation this information is stored inside the block allocated by new[]
expression, which is why the memory size requested in the implicit call to operator new[]
is normally greater than the product of the number of elements and the element size. The extra space is used to store the household information (number of elements, namely). Later delete[]
expression will retrieve that household information and use it to invoke the correct number of destructors before actually freeing the memory by calling operator delete[]
.
In your example you are not using any of these mechanisms. In your example you are calling memory allocation functions explicitly, perform construction manually and completely ignore the destruction step (which is OK, since your object has trivial destructor), which means that at least for destruction purposes you don't need to track the exact number of elements in the array. In any case, you keep track of that number manually, in a no
variable.
However, in general case it is not possible. In general case the code will use new[]
expressions and delete[]
expressions and the number of elements will have to get from new[]
to delete[]
somehow, meaning that it has to be stored internally, which is why there's a need for a dedicated memory allocation function for arrays - operator new[]
. It is not equivalent to a mere operator new
with the aforementioned product as size.
In your example code, you're using placement new
to perform the construction that operator new[]
performs automatically - with the difference that new[]
will only perform default construction and you're performing a non-default placement construction.
The following is more or less equivalent to your example:
#include <iostream>
using namespace std;
struct X
{
int data_;
X(int v=0):data_(v){}
};
int main(int argc, char* argv[])
{
unsigned no = 10;
X* xp = new X[no];
for (unsigned i = 0; i < no; ++i) {
X tmp(i);
xp[i] = tmp;
}
for (unsigned i = 0; i < no; ++i)
{
cout << (xp[i]).data_ << '\n';
}
delete[] xp;
return 0;
}
The differences in this example are:
new
is a pretty advanced technique that isn't often used, so isn't often understood)I think that in general, using new[]
/delete[]
is a much better than allocating raw memory and using placement new
to construct the objects. It pushes the complexity of the bookkeeping into those operators instead of having it in your code. However, if the cost of the "default construct/set desired value" pair of operations is found to be too costly, then the complexity of doing it manually might be worthwhile. That should be a pretty rare situation.
Of course, any discussion of new[]
/delete[]
needs to mention that using new[]
/'delete[]should probably be avoided in favor of using
std::vector`.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With