Использование malloc вместо new и вызов конструктора копирования при создании объекта - PullRequest
4 голосов
/ 10 февраля 2011

Я хотел попробовать TBable scalable_allocator, но был сбит с толку, когда мне пришлось заменить часть моего кода.Вот как распределение выполняется с помощью распределителя:

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

РЕДАКТИРОВАТЬ: выше показано не то, как выполняется распределение с помощью scalable_allocator.Как ymett правильно упомянул , распределение выполняется следующим образом:

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

Это похоже на использование malloc:

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

Это кодЯ хотел заменить:

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

Итак, попробовал программу:

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

и здесь я обнаружил, что вызов malloc не создает объект (ранее я никогда не использовал malloc).Поэтому, прежде чем выяснить, как передать *this в ctor-копию, я бы хотел узнать, как создать экземпляр объекта при работе с malloc.

Ответы [ 3 ]

21 голосов
/ 10 февраля 2011

Вам нужно будет использовать placement new после получения необработанной памяти от malloc.

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

Когда вы закончите с объектом, вы должны явно вызвать его деструктор.

s->~S();
free(mem);
9 голосов
/ 10 февраля 2011

Использование размещение новых

#include <memory>
//...
int main()
{
        S* s = (S*) malloc(sizeof(S));
        s = new (s) S();//placement new
        //...
        s->~S();
        free(s);
}
0 голосов
/ 10 февраля 2011

Параметр allocate() - это количество объектов, а не размер в байтах. Затем вы вызываете функцию construct() распределителя для создания объекта.

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

Если вы хотите использовать его со стандартным контейнером библиотеки или другим типом, осведомленным о распределителе std, просто укажите тип распределителя.

std::vector<SomeClass, scalable_allocator<SomeClass>> v;
...