开发者

Using malloc instead of new, and calling the copy constructor when the object is created

开发者 https://www.devze.com 2023-02-10 04:51 出处:网络
I wanted to try out TBB\'s scalable_allocator, but was confused when I had to replace some of my code.

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 开发者_StackOverflowwanted 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;
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号