0
I have a problem with placement new along with a "homemade allocator". The problem is that for data types (int) it works well, now for double, they start to trim very strange outputs. The classes:
#include <cstdlib>
template<class T> class my_allocator {
public:
T* allocate(size_t n);
void deallocate(T* p, size_t n);
void construct(T* p, const T& v);
void destroy(T* p);
};
template<class T>
T* my_allocator<T>::allocate(size_t n)
{
return (T*) malloc(n);
}
template<class T>
void my_allocator<T>::destroy(T* p)
{
if( p )
p->~T();
}
template<class T>
void my_allocator<T>::construct(T* p, const T& v)
{
char* z = (char*) p;
char* q = (char*) &v;
for( int i = 0; i < sizeof(p); ++i )
z[i] = q[i];
}
template<class T>
void my_allocator<T>::deallocate(T* p, size_t n)
{
for( int i = 0; i < n; ++i )
free(p);
}
#include "my_allocator.h"
#include <iostream>
using namespace std;
template<class T, class A = my_allocator<T> > class vector2 {
A alloc;
T* elem;
int sz;
int space;
public:
vector2(): sz(0), space(0) { }
explicit vector2(int s);
vector2(const vector2&);
vector2& operator=(const vector2&);
~vector2() { delete[] elem; }
T& operator[](int n) { return elem[n]; }
const T& operator[](int n) const { return elem[n]; }
int size() const { return sz; }
int capacity() const { return space; }
void copy(const vector2& arg);
void resize(int newsize, T val = T());
void push_back(const T& d);
void reserve(int newalloc);
};
template<class T>
void* operator new[](size_t n, my_allocator<T>& d)
{
return d.allocate(n);
}
template<class T, class A>
void vector2<T, A>::reserve(int newalloc)
{
if( newalloc <= space )
return;
T* p = new (alloc) T[newalloc];
for( int i = 0; i < sz; ++i )
alloc.construct(&p[i], elem[i]);
for( int i = 0; i < sz; ++i )
alloc.destroy(&elem[i]);
alloc.deallocate(elem, space);
elem = p;
space = newalloc;
}
template<class T, class A>
void vector2<T, A>::push_back(const T& val)
{
if( !space )
reserve(8);
else if( sz == space )
reserve(2*space);
alloc.construct(&elem[sz], val);
++sz;
}
I am using "placement new correctly"?
Thank you very much William!
– Wilson Junior
Good, the original Construct() would work with int and double, but would cause a problem with any more elaborate type (with pointer members or member-references).
– epx