问题
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.
回答1:
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);
回答2:
Use placement new
#include <memory>
//...
int main()
{
S* s = (S*) malloc(sizeof(S));
s = new (s) S();//placement new
//...
s->~S();
free(s);
}
回答3:
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