My C++ program needs a block of uninitialized memory and a void*
pointer to that block so that I can give it to a third party library. I want to pass control of the block lifetime to the library, so I don't want to use std::vector
. When the library is done with the block it will call a callback that I have to supply and that will deallocate the block. In C I would use malloc()
and later free()
.
In C++ I can either call ::operator new
or ::operator new[]
and ::operator delete
or operator delete[]
respectively later:
void* newBlock = ::operator new( sizeOfBlock );
// then, later
::operator delete( newBlock );
Looks like both ::operator new
and ::operator new[]
have exactly the same signature and exactly the same behavior. The same for ::operator delete
and ::operator delete[]
. The only thing I shouldn't do is pairing operator new
with operator delete[]
and vice versa - undefined behavior. Other than that which pair do I choose and why?
Use new
with a single object and new[]
with an array of objects. So, for example:
int* x = new int; // Allocates single int int* y = new int[5]; // Allocates an array of integers *x = 10; // Assignment to single value y[0] = 8; // Assignment to element of the array
If all you are doing is allocating a memory buffer, then allocate an array of char
as in:
int bufferlen = /* choose a buffer size somehow */ char* buffer = new char[bufferlen]; // now can refer to buffer[0] ... buffer[bufferlen-1]
However, in C++, you should really use std::vector
for arbitrary arrays, and you should use std::string
for character arrays that are to be interpreted or used as strings.
There is no reason to invoke ::operator new
or ::operator new[]
explicitly rather than using the ordinary syntax for these calls. For POD and primitive types (e.g. char
) no initialization will take place. If you need to get a void*
buffer, then simply use static_cast
to convert char*
to void*
.
The advantage of the C++ new
operators over C's malloc()
and free()
is that the former throws an exception if there is not enough memory, rather than returning NULL
.
Regarding choosing new(size) and new[] for character buffers, I'd advocate the latter since it is less likely to surprise people maintaining the code later i.e. char* buf = new char[size]
and delete[] buf
.
The values in the buffer will not be initialised, and there is no range-checking - you have to build a nice C++ object to do that for you, or use an existing object such as std::vector
or std::string
.
The question cannot be answered sensibly.
Firstly, it is said that the program 'needs' a block of uninitialized memory but, from the code sample given, it seems that the program 'needs' a block of uninitialized and UNTYPED memory which seems not very C++ or OO.
Secondly, a std::vector gives sole and automatic control over a block of typed memory that may or may not change in size according to its use. You can lose this control if an instance of std::vector is created on the heap and tracked with raw pointers just as for any other C or C++ object such as a void* memory block.
Thirdly, what is the intended use of this memory block? The answer to this may or may not dictate the use of operator new or operator new[]. In the design of this program, is there a single interpretation of this memory block? What ownership semantics do you require, if any? Etc, etc.
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