c语言的malloc或者heapAlloc怎么实现new的这种功能?

时间:2021-01-09 03:17:48
     比如现在有一个类, 
class test{
public:
test():var1(2),var2(3)
{

}
int var1,var2;
};


现在我 test* pTest = new test; 这样pTest指向的内存算已生成的test对象了吧, 那么构造函数应该也执行了,这段内存中肯定有某个地方被赋值为 2和3

但是如果这样写test* pTest = (test *)malloc(sizeof(test)); 这样的话pTest只是指向长度为sizeof(test)的内存, 而内存里面全是脏数, 构造函数应该也没执行。

那C语言的malloc怎么办呢?

4 个解决方案

#1


你想问的是c语言如何模拟构造函数吗?
还是说c++里用malloc却又想调构造函数?

#2


可以用 placement new 来调用构造函数:

void* addr = malloc(sizeof(test));
test* pTest = new (addr) test;

#3


malloc不支持C++的对象创建,因为C里面没有对象,不需要调用构造函数。
在C++中也不行,因为作为非模板函数的malloc不知道去调用哪个类的构造函数。
写成模板函数之后才可以,但它也只能调用缺省构造函数,不能为构造函数提供参数。
为了能带参数构造函数,需要用模板加重载:

template<typename T>
T * alloc_object()
{
   T * result = malloc(sizeof(T));
   new (T)result;
   return result;
}

template<typename T, typename P1>
T * alloc_object(P1 const & p1 )
{
    T * result = malloc(sizeof(T));
    new (T)result(p1);
    return result;
}
template<typename T, typename P1, typename P2>
T * alloc_object(P1 const & p1, P2 const & p2 )
{
    T * result = malloc(sizeof(T));
    new (T)result(p1,p2);
    return result;
}
...
调用时:
int * x = alloc_object<int>(); //x = new int;
int * y = alloc_object<int>( 5 ); //y = new int(5);
complex a = alloc_object<complex>( 3, 4) //a = new complex(3,4);


这样写起来很麻烦,而且也没必要。

如果你是想要让对象有自定义的内存分配方案,可以这样做:

class base_class
{
public:
   void * operator new( size_t size )
   {
       return malloc(size);//可以换成自己的内存分配函数
    }
    void operator delete( void * p, size_t size )
   {
      free(p);//可以换成自己的内存分配函数
   }
};

这样base_class以及它的派生类都将使用你定义的内存分配释放操作。如果base_class有派生类,并且你在释放内存时需要知道正确的size,那就需要给base_class加上一个虚析构函数。

如果为类写自定义new/delete操作符不能满足要求,那没别的办法了,只能使用分配内存块+placement new 操作符来实现了(如我前面写的代码),stl容器中就是这样做的,不过stl容器只会调用类的缺省构造函数和拷贝构造函数,不需要考虑那么多构造参数,自然就简单多了。

#4



T *p0 =new (malloc(sizeof(T)) T();
T *p3 =new (malloc(sizeof(T)) T(a,b,c);

.....
.....
.....

p0->~T();
free(p0);
p3->~T();
free(p3);

应该这样吧!

#1


你想问的是c语言如何模拟构造函数吗?
还是说c++里用malloc却又想调构造函数?

#2


可以用 placement new 来调用构造函数:

void* addr = malloc(sizeof(test));
test* pTest = new (addr) test;

#3


malloc不支持C++的对象创建,因为C里面没有对象,不需要调用构造函数。
在C++中也不行,因为作为非模板函数的malloc不知道去调用哪个类的构造函数。
写成模板函数之后才可以,但它也只能调用缺省构造函数,不能为构造函数提供参数。
为了能带参数构造函数,需要用模板加重载:

template<typename T>
T * alloc_object()
{
   T * result = malloc(sizeof(T));
   new (T)result;
   return result;
}

template<typename T, typename P1>
T * alloc_object(P1 const & p1 )
{
    T * result = malloc(sizeof(T));
    new (T)result(p1);
    return result;
}
template<typename T, typename P1, typename P2>
T * alloc_object(P1 const & p1, P2 const & p2 )
{
    T * result = malloc(sizeof(T));
    new (T)result(p1,p2);
    return result;
}
...
调用时:
int * x = alloc_object<int>(); //x = new int;
int * y = alloc_object<int>( 5 ); //y = new int(5);
complex a = alloc_object<complex>( 3, 4) //a = new complex(3,4);


这样写起来很麻烦,而且也没必要。

如果你是想要让对象有自定义的内存分配方案,可以这样做:

class base_class
{
public:
   void * operator new( size_t size )
   {
       return malloc(size);//可以换成自己的内存分配函数
    }
    void operator delete( void * p, size_t size )
   {
      free(p);//可以换成自己的内存分配函数
   }
};

这样base_class以及它的派生类都将使用你定义的内存分配释放操作。如果base_class有派生类,并且你在释放内存时需要知道正确的size,那就需要给base_class加上一个虚析构函数。

如果为类写自定义new/delete操作符不能满足要求,那没别的办法了,只能使用分配内存块+placement new 操作符来实现了(如我前面写的代码),stl容器中就是这样做的,不过stl容器只会调用类的缺省构造函数和拷贝构造函数,不需要考虑那么多构造参数,自然就简单多了。

#4



T *p0 =new (malloc(sizeof(T)) T();
T *p3 =new (malloc(sizeof(T)) T(a,b,c);

.....
.....
.....

p0->~T();
free(p0);
p3->~T();
free(p3);

应该这样吧!