tags:

views:

599

answers:

8

Is it possible to allocate an arbitrary memory block using the "new" operator? In C I can do it like "void * p = malloc(7);" - this will allocate 7 bytes if memory alignment is set to 1 byte. How to make the same in C++ with the new operator?

+6  A: 

You can't allocate a void pointer with C++'s operator new: you'll have to allocate an explicit type such as char or uint8_t:

char *p = new char[7];
uint8_t *q = new uint8_t[7];
...
delete [] p;
delete [] q;
Adam Rosenfield
+1  A: 

I think you might be looking for Placement New.

Kristo
I would only add that if you are going to be using such techniques as the Placement New you HAVE TO BE CAREFUL. Only use it if really necessary!!
Miky Dinescu
How does placement new relate to allocating memory?
avakar
@Miky D: I agree, which is why the linked page is sprinkled with the word "DANGER" in all caps. :-)
Kristo
Maybe I misunderstood the question, but I believe that it is asking about just the opposite. That is, not how to create/initialize an object in an already allocated memory space, but rather how to allocate the memory without performing the constructor call.
David Rodríguez - dribeas
+2  A: 

new char[7];

Traditionally, char is a byte, though you might find some libraries that typedef a BYTE type.

Stefan Mai
Doesn't matter; a char is the smallest type the implementation can handle. If a char is 16 bits, then a byte type cannot be less than 16 bits. Remember that sizeof(char) == 1. Always.
David Thornley
@David Thornley: sizeof(char) is not necessary 1, otherwise all sorts of marshalling libraries will get terribly upset.
florin
@florin: sizeof(char) == 1 according to the standard. See section 5.3.3 of the ISO/IEC 14882:2003. "sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1; the result of sizeof applied to any other fundamental type (3.9.1) is implementation-defined."
Evan Teran
Um, yes, sizeof(char) == 1. At least according to section 5.3.3 of the ISO C++ standard (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2914.pdf), but let's not be boring, I like this response to the question more: http://www.parashift.com/c++-faq-lite/intrinsic-types.html#faq-26.1
Andreas Magnusson
@Andreas: isn't that what I just said?
Evan Teran
@Evan: I wrote the comment at the same time. Your comment wasn't visible until after i pressed the button. As I have some good references in mine I decided to keep it even though it basically says the same thing.
Andreas Magnusson
+2  A: 

You can do char* pBuffer = new char[7];, and since the sizeof(char) is 1 byte you can use it as a byte buffer. Also, remember to use delete[] (with []) when releasing the memory.

Naveen
+9  A: 

Others have answered the question as written but I'd like to suggest sticking with malloc/free for such allocations.

new and delete are for allocating objects. They allocate the memory required and call constructors/destructors. If you know that you just need an arbitrary block of memory, using malloc and free is perfectly reasonable.

dominic hamon
But if you are writing C++ code I think it is better to use new/delete since you'll be using it to allocate the objects. Having two types of memory allocation functions adds more the confusion.
Naveen
-1. new/delete are language constructs and introduce type safety no matter what you allocate/deallocate. malloc/free are artifacts remaining for backwards compatibility.
sharkin
@RA, if one needs an arbitrary generic block of bytes, there's no gain in making believe they're specifically char or unsigned char or whatever -- a void* is more honest and explicit. +1 for malloc!
Alex Martelli
The OP explicitly states that they expect a void pointer back. As such, using new/delete will introduce types where they may not want them.If the use-case is actually going to be as an array of types then absolutely switch to new[]. If they're just managing a block of memory, there's no reason to introduce types.
dominic hamon
+1 from here. Yes, new/delete add type safety, but if he is not wanting to allocate any specific types, but simply a blank memory buffer, then malloc/free does exactly that.
jalf
Though you should go through operator new, like the accepted answer, because they might be overridden to do something.
GMan
+32  A: 

Arbitrary memory blocks can be allocated with operator new in C++; not with the new operator which is for constructing objects.

void* pBlock = ::operator new(7);

Such blocks can subsequently be freed with operator delete.

::operator delete(pBlock);

Note that operator new will allocated memory suitably aligned for any sort of object, so the implementation might not allocate exactly seven bytes and no more, but the same is (usually) true of malloc. C clients of malloc usually need aligned memory too.

Charles Bailey
Johannes Schaub - litb
Also, be aware that operator new usually just passes the buck to malloc() anyways (on every implementation I'm aware of). As dominic said, might as well just use malloc.
Drew Hall
Thanks a lot. That's an answer ("::operator new"). I spent a lot of time trying to figure out why the ":: new(x);" doesn't work :)
+2  A: 

Yes you can.
But depending on what you are doing there may be better techniques.

Can you update the question and tell us what you are trying to achieve. With more context a better solution could be provided.

An Example:
If you were dynamically allocating a buffer to read from a socket (because the size is not known at compile time). An alternative would be to use a vector and dynamically size that. You can then get a pointer to the inside of the buffer by taking the address of the first element.

Martin York
+2  A: 

Personally I would use a std::vector<char>. Not only do you get an arbitrary block of bytes (guaranteed to be contiguous), you get them in an RAII wrapper. Of course, there's no need to use any of std::vector's methods (aside from, maybe, resize()), but there's no penalty for that:

std::vector<char> buffer(7);
void* p = &buffer[0];

You could use a std::string, but std::string implies "this object contains characters that make sense when printed out," where a std::vector<char> implies "this object contains an arbitrary group of bytes."

Max Lybbert