Using malloc instead of new and calling the copy constructor when creating an object

I wanted to try TBB scalable_allocator, but was confused when I had to replace part of my code. So distributed with the distributor:

SomeClass* s = scalable_allocator<SomeClass>().allocate( sizeof(SomeClass) ); 

EDIT: What is shown above is not how distribution is done using scalable_allocator. Since ymett is correctly specified , the selection is done as follows:

 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); 

This is very similar to using malloc:

 SomeClass* s = (SomeClass*) malloc (sizeof(SomeClass)); 

This is the code I would like to replace:

 SomeClass* SomeClass::Clone() const { return new SomeClass(*this); }//Clone 

So, I tried the 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(si) {} }; 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 have never used malloc before). Therefore, before figuring out how to pass *this to a copy of ctor, I would like to know how to instantiate an object when working with malloc.

+4
source share
3 answers

You will need to use placement new after receiving raw memory from malloc .

 void* mem = malloc(sizeof(S)); S* s = new (mem) S(); //this is the so called "placement new" 

When you are done with the object, you need to explicitly call its destructor.

 s->~S(); free(mem); 
+20
source

Use new placement

 #include <memory> //... int main() { S* s = (S*) malloc(sizeof(S)); s = new (s) S();//placement new //... s->~S(); free(s); } 
+8
source

The allocate() parameter is the number of objects, not the size in bytes. Then you call the allocator construct() function to build the object.

 scalable_allocator<SomeClass> sa; SomeClass* s = sa.allocate(1); sa.construct(s, SomeClass()); // ... sa.destroy(s); sa.deallocate(s); 

If you want to use it with a standard library container or other standard dispenser type, simply specify the dispenser type for it.

 std::vector<SomeClass, scalable_allocator<SomeClass>> v; 
0
source

Source: https://habr.com/ru/post/1339173/


All Articles