I was asked an interview question: How can we allocate two objects of a class in different functions using the new operator such that they use the same memory space?
Can anyone explain how this can be achieved? Thanks.
EDIT: So the main question was how to create a class Memory_Alloc which should be used by all other classes to allocate memory for their objects. I thought about using Handles. Then he asked me the above question.
The question is a little vague, but off the top of my head you could use:
placement new -- use the new operator to initialize the same memory address
overloaded new operator -- overload the new operator to return the same address
delegation -- using pointer to implementation idiom, make two objects point to the same implementation object
Impossible, because two objects always occupy different addresses, which is also the reason empty objects still have a size greater than zero. That said, for a trick question, you could create an object, destroy it again, and create another object at the same location.
Now, there is one question left: What exactly is a "memory space"? Did the interviewer mean address space perhaps?
How can we allocate two objects of a class in different functions using the new operator such that they use the same memory space?
Use placement new operator to do that.
Normally, the new operator has the responsibility of finding in the heap a block of memory
that is large enough to handle the amount of memory you request.The new operator
is called placement new, that allows you to specify the location to be used.
You could use this feature to set up your own memory-management procedures or to deal with hardware that is accessed via a particular address or to construct objects in a particular memory location.
struct AType
{
};
void func(AType*& p)
{
p = new (p) AType;
}
int main()
{
AType *p1 = new AType;
func(p1);
}
Also see placement new wiki link
With placement-new:
/* define class Foo */
void fun1(void * p) { ::new (p) Foo; }
void fun2(void * p) { ::new (p) Foo; }
int main()
{
void * p = ::operator new(sizeof(Foo));
fun1(p);
p->~Foo();
fun2(p);
p->~Foo();
::operator delete(p);
}
Don't ever write code like that.
Related
In his new book TC++PL4, Stroustrup casts a slightly different light on a once usual practice regarding user-controlled memory allocation and placement new—or, more specifically, regarding the enigmatical "placement delete." In the book's sect. 11.2.4, Stroustrup writes:
The "placement delete" operators do nothing except possibly inform a garbage collector that the deleted pointer is no longer safely derived.
This implies that sound programming practice will follow an explicit call to a destructor by a call to placement delete.
Fair enough. However, is there no better syntax to call placement delete than the obscure
::operator delete(p);
The reason I ask is that Stroustrup's sect. 11.2.4 mentions no such odd syntax. Indeed, Stroustrup does not dwell on the matter; he mentions no syntax at all. I vaguely dislike the look of ::operator, which interjects the matter of namespace resolution into something that properly has nothing especially to do with namespaces. Does no more elegant syntax exist?
For reference, here is Stroustrup's quote in fuller context:
By default, operator new creates its object on the free store. What
if we wanted the object allocated elsewhere?... We can place objects
anywhere by providing an allocator function with extra arguments and
then supplying such extra arguments when using new:
void* operator new(size_t, void* p) { return p; }
void buf = reinterpret_cast<void*>(0xF00F);
X* p2 = new(buf) X;
Because of this usage, the new(buf) X syntax for supplying extra
arguments to operator new() is known as the placement syntax.
Note that every operator new() takes a size as its first argument
and that the size of the object allocated is implicitly supplied.
The operator new() used by the new operator is chosen by the
usual argument-matching rules; every operator new() has
a size_t as its first argument.
The "placement" operator new() is the simplest such allocator. It
is defined in the standard header <new>:
void* operator new (size_t, void* p) noexcept;
void* operator new[](size_t, void* p) noexcept;
void* operator delete (void* p, void*) noexcept; // if (p) make *p invalid
void* operator delete[](void* p, void*) noexcept;
The "placement delete" operators do nothing except possibly inform a
garbage collector that the deleted pointer is no longer safely
derived.
Stroustrup then continues to discuss the use of placement new with arenas. He does not seem to mention placement delete again.
If you don't want to use ::, you don't really have to. In fact, you generally shouldn't (don't want to).
You can provide replacements for ::operator new and ::operator delete (and the array variants, though you should never use them).
You can also, however, overload operator new and operator delete for a class (and yes, again, you can do the array variants, but still shouldn't ever use them).
Using something like void *x = ::operator new(some_size); forces the allocation to go directly to the global operator new instead of using a class specific one (if it exists). Generally, of course, you want to use the class specific one if it exists (and the global one if it doesn't). That's exactly what you get from using void *x = operator new(some_size); (i.e., no scope resolution operator).
As always, you need to ensure that your news and deletes match, so you should only use ::operator delete to delete the memory when/if you used ::operator new to allocate it. Most of the time you shouldn't use :: on either one.
The primary exception to that is when/if you're actually writing an operator new and operator delete for some class. These will typically call ::operator new to get a big chunk of memory, then divvy that up into object-sized pieces. To allocate that big chunk of memory, it typically (always?) has to explicitly specify ::operator new because otherwise it would end up calling itself to allocate it. Obviously, if it specifies ::operator new when it allocates the data, it also needs to specify ::operator delete to match.
First of all: No there isn't.
But what is the type of memory? Exactly, it doesn't have one. So why not just use the following:
typedef unsigned char byte;
byte *buffer = new byte[SIZE];
Object *obj1 = new (buffer) Object;
Object *obj2 = new (buffer + sizeof(Object)) Object;
...
obj1->~Object();
obj2->~Object();
delete[] buffer;
This way you don't have to worry about placement delete at all. Just wrap the whole thing in a class called Buffer and there you go.
EDIT
I thought about your question and tried a lot of things out but I found no occasion for what you call placement delete. When you take a look into the <new> header you'll see this function is empty. I'd say it's just there for the sake of completeness. Even when using templates you're able to call the destructor manually, you know?
class Buffer
{
private:
size_t size, pos;
byte *memory;
public:
Buffer(size_t size) : size(size), pos(0), memory(new byte[size]) {}
~Buffer()
{
delete[] memory;
}
template<class T>
T* create()
{
if(pos + sizeof(T) > size) return NULL;
T *obj = new (memory + pos) T;
pos += sizeof(T);
return obj;
}
template<class T>
void destroy(T *obj)
{
if(obj) obj->~T(); //no need for placement delete here
}
};
int main()
{
Buffer buffer(1024 * 1024);
HeavyA *aObj = buffer.create<HeavyA>();
HeavyB *bObj = buffer.create<HeavyB>();
if(aObj && bObj)
{
...
}
buffer.destroy(aObj);
buffer.destroy(bObj);
}
This class is just an arena (what Stroustrup calls it). You can use it when you have to allocate many objects and don't want the overhead of calling new everytime. IMHO this is the only use case for a placement new/delete.
This implies that sound programming practice will follow an explicit call to a destructor by a call to placement delete.
No it doesn't. IIUC Stroustrup does not mean placement delete is necessary to inform the garbage collector that memory is no longer in use, he means it doesn't do anything apart from that. All deallocation functions can tell a garbage colector memory is no longer used, but when using placement new to manage memory yourself, why would you want a garbage collector to fiddle with that memory anyway?
I vaguely dislike the look of ::operator, which interjects the matter of namespace resolution into something that properly has nothing especially to do with namespaces.
"Properly" it does have to do with namespaces, qualifying it to refer to the "global operator new" distinguishes it from any overloaded operator new for class types.
Does no more elegant syntax exist?
You probably don't ever want to call it. A placement delete operator will be called by the compiler if you use placement new and the constructor throws an exception. Since there is no memory to deallocate (because the pacement new didn't allocate any) all it does it potentially mark the memory as unused.
Hello So I'm experimenting with creating objects and arrays with preallocated memory. For instance I have this following code:
int * prealloc = (int*)malloc(sizeof(Test));
Test *arr = new(prealloc) Test();
Where test is defined as follows:
class Test {
public:
Test() {
printf("In Constructor\n");
}
~Test() {
printf("In Destructor\n");
}
int val;
};
In this scenario if I call delete it will actually release the memory which is bad, b/c maybe I'm using some type of memory manager so this will sure cause some problems. I searched in the internet and the only solution that I found was to call the destructor explicitly and then call free:
arr->~Test();
free(arr);
Is there another way to do this? is there perhaps a way to call delete and tell it to just call the destructor and not to release the memory?
My second problem was when working with arrays, like the previous example you can pass to new the pre-allocated memory:
int * prealloc2 = (int*)malloc(sizeof(Test) * 10);
Test *arr2 = new(prealloc2) Test[10];
If I call delete[] it will not only call the destructor for each element in the array but it will also release the memory which is something I don't want. The only way I have found that it should be done is to go through the array and call the destructor explicitly, and then call free. Like with the regular none array operators is there a way to tell the operator to just call the destructors without releasing the memory?
One thing I did notice was that the new operator for an array will actually use the first 4 bytes to store the size of the array (I only tested this in visual studio with a 32 bit build) That would help me know how many elements the array has but there is still one problem. What if the array is a pointer array? for example:
Test **arr2 = new Test*[10];
Could someone help me out with these questions please.
It's normal and expected to directly invoke the destructor to destroy objects you've created with placement new. As far as any other way to do things, about the only obvious alternative is to use an Allocator object (which, at least 99% of the time, will just be a wrapper around placement new and directly invoking the destructor).
Generally speaking, you do not want to use new[] at all. You typically want to allocate your raw memory with operator new (or possibly ::operator new) and release it with the matching operator delete or ::operator delete.
You create objects in that memory with placement new and destroy them by directly invoking the destructor.
There is no other way to do it but to explicitly call the destructor as delete will also attempt to free the memory.
Using preallocated memory with placement new should be fairly rare in your code - a typical use case is when you're dealing with direct memory mapped hardware interfaces when you want/need to map an object on top of a fixed memory address - and is something I'd normally consider a code smell.
If you want to tweak the memory management for a specific class, you're much better off either using an STL container with a custom allocator or overload operators new and delete for that specific class.
Yes, this is the only way to do it. There is an asymmetry in being allowed to define new but not delete. [ Well, you can do the latter but it can only get called when new throws an exception (not handled properly below!)
You can use a templated destroy to achieve the same result:
class Test
{
public:
Test() {
printf("In Constructor\n");
}
~Test() {
printf("In Destructor\n");
}
int val;
};
class Allocator
{
public:
static void* allocate(size_t amount) { return std::malloc(amount);}
static void unallocate(void* mem) { std::free(mem);}
static Allocator allocator;
};
Allocator Allocator::allocator;
inline void* operator new(size_t size, const Allocator& allocator)
{
return allocator.allocate(size);
}
template<class T>
void destroy(const Allocator& allocator, T* object)
{
object->~T();
allocator.unallocate(object);
}
int main()
{
Test* t = new (Allocator::allocator) Test();
destroy(Allocator::allocator, t);
return 0;
}
Is there a way to get size of a single element or element count allocated using operator new[] ?
What I mean:
void* Object::operator new[](size_t size)
{
void *temp = ::operator new(size);
//Get size of single element or count of elements being allocated
return temp;
}
Why I need it:
operator new(size_t) and operator new[](size_t) are invoked only when object is allocated on heap so I've got an idea of creating c++ garbage collection based on this.
All objects inherit from Object class
Object class overrides operator new(size_t) and operator new[](size_t)like this:
void* Object::operator new(size_t size)
{
Object& result = *static_cast<Object*>(::operator new(size));
result.referenceCount = (int)&result;
return &result;
}
Constructor of Object uses this information:
Object::Object()
{
if ((void*)referenceCount != this)
{
referenceCount = -1; //stack object no reference counting
}
else
{
referenceCount = 1; //heap object count references
}
}
Garbage Collector user referenceCount field to work with.
What I need now is to implement operator new[](size_t) to set referenceCount and that is why I need size of single element or element count. Impelenting operator new[](size_t) for every object out of the question.
Any ideas?
This seems very Java-esque to me. Would it be simpler to simply write your program in Java? Anyone who has to maintain your C++ code in the future will appreciate it if you use idiomatic C++ to start with. For example use smart pointers to manage your memory rather than trying to implement garbage collection based on everything inheriting from Object.
I should point out that you left out "multiple inheritance is prohibited" from your list of conditions because in the presence of multiple inheritance your cast of raw, uninitialized memory to an Object* may not do the pointer adjustments it needs to to access the correct address of referenceCount.
Additionally if the memory of referenceCount happens to hold the address of a stack-based Object at construction your code will believe it to be heap-allocated and eventually result in UB when you delete a stack pointer.
But after all that if you still really really really want to do this, I think your only option is to use CRTP to automatically inject the array new operator into each child class. At least that way you don't have to write it yourself for every child.
I have a question regarding placement new syntax in C++. Are the following two code snippets functionally equivalent and can be used interchangeably (I am not implying that the second should be used, when the first one is suitable)?
#1
T* myObj = new T();
// Do something with myObj
delete myObj;
#2
char* mem = new char[sizeof(T)];
T* myObj = new (mem) T();
// Do something with myObj
myObj->~T();
delete[] mem;
Is there something I should be especially careful of, when I am using the placement new syntax like this?
They are not equivalent, because they have different behaviour if the constructor or the destructor of T throws.
new T() will free any memory that has been allocated before letting the exception propagate any further. char* mem = new char[sizeof(T)]; T* myObj = new (mem) T(); will not (and unless you explicitly do something to ensure that it gets freed you will have a leak). Similarly, delete myObj will always deallocate memory, regardless of whether ~T() throws.
An exact equivalent for T* myObj = new T();/*other code*/delete myObj; would be something like:
//When using new/delete, T::operator new/delete
//will be used if it exists.
//I don't know how do emulate this in
//a generic way, so this code just uses
//the global versions of operator new and delete.
void *mem = ::operator new(sizeof(T));
T* myObj;
try {
myObj = new (mem) T();
}
catch(...) {
::operator delete(mem);
throw;
}
/*other code*/
try {
myObj->~T();
::operator delete(mem);
}
catch(...) {
//yes there are a lot of duplicate ::operator deletes
//This is what I get for not using RAII ):
::operator delete(mem);
throw;
}
Since you're allocating raw memory, a closer equivalent would be:
void *mem = operator new(sizeof(T));
T *myobj = new(mem) T();
// ...
myobj->~T();
operator delete(mem);
Note that if you've overloaded ::operator new for a particular class, this will use that class' operator new, where yours using new char [] would ignore it.
Edit: though I should add that I'm ignoring the possibility of exceptions here. #Mankarse's answer seems (to me) to cover that part fairly well.
On a fundamental level, you're doing the same thing in both situations: i.e. you're instantiating a new object on the heap and you're releasing the memory, but in the second case you're (obviously) using the placement new operator.
In this case both of them would yield the same results, minus the differences if the constructor throws as Mankarse explained.
In addition, I wouldn't say that you can use them interchangeably, because the second case is not a realistic example of how placement new is used. It would probably make a lot more sense to use placement new in the context of a memory pool and if you're writing your own memory manager so you can place multiple T objects on the per-allocated memory (in my tests it tends to save about 25% CPU time). If you have a more realistic use case for placement new then there will be a lot more things that you should worry about.
Well, you are pre-allocating memory for your T object. And it should be fine. Nevertheless it makes sense if you will reuse allocated area one more time. Otherwise It will be slower.
Yes. Your example is too simple to demonstrate this, but the memory you allocated in advance, "mem," should manage the object stored within, "myObj."
Perhaps put a better way, scenario #1 allocates space on the heap, and constructs an object in that space. Scenario #2 allocates space on the heap, "mem," then constructs an object somewhere within that space.
Now, put a second object somewhere else within "mem." It gets complicated, right?
The construction and destruction of myObj are happening identically in both scenarios (except in the case of your constructor throwing an exception, as pointed out by Mankarse), but the allocator is taking care of your memory management for you in scenario #1, and not in scenario #2.
So, be careful of managing "mem" appropriately. One common approach is the following:
template<class T> void destroy(T* p, Arena& a)
{
if (p) {
p->~T(); // explicit destructor call
a.deallocate(p);
}
}
I have encountered the following code:
class a {
public:
void * operator new(size_t l, int nb);
double values;
};
void *a::operator new (size_t l,int n)
{
return new char[l+ (n>1 ? n - 1 : 0)*sizeof(double)];
}
From what I get it is then used to have an array like structure that start at "values":
double* Val = &(p->a->values) + fColumnNumber;
My question is :
is there a memory leak? I am very new to overloading new operator, but I'm pretty sure that the memory allocated is not deallocated properly. Also does that mean I can never create a "a" class on the stack?
thanks
I believe it technically produces UB as it is, though it's a form of UB that will probably never cause a visible side effect (it's using new [], but I believe that'll get matched up with delete -- but for char, this usually won't cause a visible problem).
IMO, it's almost worse that it's using a new expression to allocate what should really be raw bytes instead of objects. If I were doing it, I'd write it like:
void *a::operator new (size_t l,int n)
{
return ::operator new(l+ (n>1 ? n - 1 : 0)*sizeof(double));
}
You'd match that up with:
void a::operator delete(void *block)
{
::operator delete(block);
}
I don't see why the default operator delete called on an a * wouldn't be able to correctly deallocate the memory allocated by this custom operator new. The best way to check would be to actually write some code and find out, although rather than rob05c's technique I'd probably run it in a profiler such as valgrind. I assume the questioner sees a memory leak happening and suspects this as the cause, so writing a test case around this operator seems like a worthwhile endeavour.
Obviously it will leak if nobody gets around to actually deleting it afterwards...
I'd question the necessity of overriding new for this kind of functionality, but I also assume this was somebody else's code.
It's fairly easy to find out. Write a loop that constructs and deconstructs lots of a's, and watch your memory usage. It'll go up pretty fast if it's leaking.
Its fine as it is, but you'd need to use delete[], not delete, from the code that uses this class as it allocates an array. Note that the user wouldn't get any hints that they need to do this - so overloading a delete operator for them would be a good idea.
You can definitely create Class "a" on the stack.
There are 4 (actually more but will stick with the basics) new & delete method signatures you should know.
void* operator new (std::size_t size) throw (std::bad_alloc);
void* operator new[] (std::size_t size) throw (std::bad_alloc);
void operator delete (void* ptr) throw ();
void operator delete[] (void* ptr) throw ();
You are allocating an array within the "operator new" method which should be done in the "operator new[]" method. This will get rid of your nasty check. Write both, "operator new" and "operator new[]"
Don't forget you want to give the caller an object of type "a" ( a myA = new a) so make sure you return "a" not char*, therefore you need to also be casting.
You need to write the corresponding delete[] and delete methods.
To answer your question, I believe it does leak memory. The new signature you've provided is called the "placement new". This allows you to allocate a new pointer without allocating memory but to give it a location to point to. Example: If you needed a pointer to a specific point in memory.
long z = 0x0F9877F80078;
a myA = new (z) a[5]; // 5 pointers that point to 0x0F9877F80078
By definition the placement-new operator is not supposed to allocate memory and since you have you make be leaking. Get rid of your second argument, which you can do now since you have 2 versions of operator new and you're good to go. Don't forget to return an object "a".
Check out IBM's Info Center:
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr318.htm
And the reference or references, cpluplus.com:
http://www.cplusplus.com/reference/std/new