I wanted to try out TBB's scalable_allocator, but was confused when I had to replace some of my code. This is how allocation is done with the allocator:
SomeClass* s = scalable_allocator<SomeClass>().allocate( sizeof(SomeClass) );
EDIT: What's shown above is not how allocation is done with scalable_allocator. As ymett correctly mentioned, allocation is done like this:
int numberOfObjectsToAllocateFor = 1;
SomeClass* s = scalable_allocator<SomeClass>().allocate( numberOfObjectsToAllocateFor );
scalable_allocator<SomeClass>().construct( s, SomeClass());
scalable_allocator<SomeClass>().destroy(s);
scalable_allocator<SomeClass>().deallocate(s, numberOfObjectsToAllocateFor);
It's pretty much like using a malloc:
SomeClass* s = (SomeClass*) malloc (sizeof(SomeClass));
This is the code I wanted to replace:
SomeClass* SomeClass::Clone() const
{
return new SomeClass(*this);
}//Clone
So tried a program:
#include<iostream>
#include<cstdlib>
using namespace std;
class S
{
public:
int i;
S() {cout<<"constructed"<<endl;}
~S() {cout<<"destructed"<<endl;}
S(const S& s):i(s.i) {}
};
int main()
{
S* s = (S*) malloc(sizeof(S));
s = (S*) S();//this is obviously wrong
free(s);
}
and here I found that calling malloc does not instantiate the object (I've never used malloc earlier). So before figuring out how to pass *this
to the copy ctor, I'd like to know how to instantiate the object when working with malloc.
You'll need to use placement new
after getting the raw memory from malloc
.
void* mem = malloc(sizeof(S));
S* s = new (mem) S(); //this is the so called "placement new"
When you're done with the object you have to make sure to explicitly call its destructor.
s->~S();
free(mem);
Use placement new
#include <memory>
//...
int main()
{
S* s = (S*) malloc(sizeof(S));
s = new (s) S();//placement new
//...
s->~S();
free(s);
}
The parameter to allocate()
is the number of objects, not the size in bytes.
You then call the allocator's construct()
function to construct the object.
scalable_allocator<SomeClass> sa;
SomeClass* s = sa.allocate(1);
sa.construct(s, SomeClass());
// ...
sa.destroy(s);
sa.deallocate(s);
If want to use it with a standard library container or other std allocator aware type, simply give it the allocator type.
std::vector<SomeClass, scalable_allocator<SomeClass>> v;
来源:https://stackoverflow.com/questions/4956249/using-malloc-instead-of-new-and-calling-the-copy-constructor-when-the-object-is