Re: [Boost-users] nondynamic: A utility class that promotes safe programming
Hello Ovanes, Ovanes wrote:
Hello Daniel,
I thought about such a class as well. The main disadvantage of it is that it is impossible to use with standard containers. :( Standard containers (e.g. std::vector) pre-allocate space for some number of instances and use the placement new operator to place items in the pre-allocated memory and when deriving form nondynamic makes it impossible.
As I understand it, the standard containers use the global placement new, which cannot be overridden. These lines are actually ok to do it seems: char dataIOBuffer[sizeof(DataIO)] = {0}; DataIO* inplaceCreated = ::new(dataIOBuffer)DataIO(IDataIOPtr()); Regardless of where I place (no pun intended) the placement new operator in nondynamic. -- Daniel
Sorry,
I mixed smth. That is true, that placement new can not be overridden. The
problem, is that you can not allocate for vector items with new[]. Because
std containers allocate some number of items using std::allocator class. C++
defines the following interface for the allocator class:
template <class T>
class allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
template <class U>
struct rebind
{ typedef allocator<U> other; };
allocator() throw();
allocator(const allocator&) throw();
template <class U>
allocator(const allocator<U>&) throw();
˜allocator() throw();
pointer address(reference x) const;
const_pointer address(const_reference x) const;
pointer allocate(size_type, allocator<void>::const_pointer hint = 0);
void deallocate(pointer p, size_type n);
size_type max_size() const throw();
void construct(pointer p, const T& val);
void destroy(pointer p);
};
size_type parameter in allcoate member function means:
The number of elements for which sufficient storage is to be allocated.
What do you think how this allocator will allocate the number of these
element? Actually in any possible way.
It can use new[] or new char[sizeof(T)*NumElems] or use an own mem-manager.
And the worse thing you can't make
allocator friend of your class, since users of containers can pass their own
allocators.
And despite all enumerated facts you will fail to compile, since the
function address will fail to return the pointer to x, because it is
prohibited in your case.
On Fri, Mar 28, 2008 at 11:33 AM, Daniel Lidström
Hello Ovanes,
As I understand it, the standard containers use the global placement new, which cannot be overridden. These lines are actually ok to do it seems:
char dataIOBuffer[sizeof(DataIO)] = {0}; DataIO* inplaceCreated = ::new(dataIOBuffer)DataIO(IDataIOPtr());
This storage is possibly not properly aligned when used like this.
Regardless of where I place (no pun intended) the placement new operator in nondynamic.
-- Daniel http://lists.boost.org/mailman/listinfo.cgi/boost-users
Sorry for misleading post before. Ovanes
AMDG Ovanes Markarian wrote:
What do you think how this allocator will allocate the number of these element? Actually in any possible way. It can use new[] or new char[sizeof(T)*NumElems] or use an own mem-manager. And the worse thing you can't make allocator friend of your class, since users of containers can pass their own allocators.
It can't use new[] because new[] constructs the elements immediately.
And despite all enumerated facts you will fail to compile, since the function address will fail to return the pointer to x, because it is prohibited in your case.
Yep. This a serious problem. overloading operator& can cause generic code to break randomly, because most people assume that &x will work. (And those that don't probably circumvent your defenses by using boost::addressof, anyway.) In Christ, Steven Watanabe
participants (3)
-
Daniel Lidström
-
Ovanes Markarian
-
Steven Watanabe