General Allocator Regarding type definitions and void * specializedproblem

This is a discussion on General Allocator Regarding type definitions and void * specializedproblem within the c++ forums in Programming Languages category; Hello all C++ expert programmer, i have wrote partial general allocator for my container. After reading standard C++ library and code guru article, i have several questions. 1. Why allocator write forward declaration then allocation for void* rather than directly wrote allocator first ? Code: namespace std { template <class T> class allocator; // specialize for void: template <> class allocator<void> { public: typedef void* pointer; typedef const void* const_pointer; // reference to void members are impossible. typedef void value_type; template <class U> struct rebind { typedef allocator<U> other; }; }; template <class T> class allocator { public: typedef size_t ...

Go Back   Application Development Forum > Programming Languages > c++

Object Mix

Register FAQ Calendar Search Today's Posts Mark Forums Read
  #1  
Old 08-14-2008, 12:21 AM
PeterAPIIT@gmail.com
Guest
 
Default General Allocator Regarding type definitions and void * specializedproblem

Hello all C++ expert programmer,

i have wrote partial general allocator for my container.

After reading standard C++ library and code guru article, i have
several questions.

1. Why allocator write forward declaration then allocation for void*
rather than directly wrote allocator first ?

Code:
namespace std {
template <class T> class allocator;

// specialize for void:
template <> class allocator<void> {
public:
typedef void*       pointer;
typedef const void* const_pointer;
// reference to void members are impossible.
typedef void value_type;
template <class U> struct rebind { typedef allocator<U>
other; };
};

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

2. What is the use/purpose of type definition ?

Quote:
1. A couple of type definitions. These ensure that the allocators'
client (for instance, 'std::vector') is able to use some relevant
types by known names. For example, consider that you write an
allocator, that is able to allocate memory in a far area, that cannot
be reached by normal pointers (let your imagination wander). Now, the
'allocator' will use some pointer-like construct. The allocators'
client has, of course, no idea of such a thing. When a client needs to
pass such a pointer it will use the

typedef T* pointer;

and if it needs to suptract such pointers, the result will have the
type 'difference_type', whatever that internally means for the
allocator.

What i understand from here is because different container needs
different pointer construct memory, therefore, there are different
member data in list and vector. So, allocator need to match back its
member data with vector for example.

Quote:
typedef T* pointer; ----------- Allocator

Vector
typedef A allocator_type; typedef typename A:ointer pointer;
Although, i not able to understand what this does

Quote:
vector
typedef A allocator_type; typedef typename A:ointer pointer;
3. How allocator know when it need rebind for its allocator
client(vector, list, map, set) ?

Quote:
This is the magic required for std::list to work properly,
since given std::list<int> ( allocator<int>() ), std::list actually
needs to allocate memory for Node<int>, and not int.
Thus, they need to rebind to allocator<int>()::rebind<Node<int> >
:ther instead.

Code:
template <class U>
struct rebind
{
typedef allocator<U> other;
};

list<int>;

interprete by compiler as list<int, allocator<int> >;

This code template <class T>
class allocator; is replace with allocator<int> >;

In other words, T(represent generic types) = int;

Then allocator class receive integer as argument

How compiler interpreter
template <class U>
struct rebind
{
typedef allocato<U> other;
}

How list is pass U ?
Thanks for your help.

Please help me.
I really appreciated any help.
Reply With Quote
  #2  
Old 08-14-2008, 01:50 AM
PeterAPIIT@gmail.com
Guest
 
Default Re: General Allocator Regarding type definitions and void *specialized problem

This is current work.

Code:

/*
Two steps define custom allocators

1. Design a memory management mechanism/model
2. Create standard-like allocators


*/



// ================================================

#ifndef _Custom_Allocator_
#define _Custom_Allocator_

#include <memory>

using std::allocator;


// ================================================

template <class T>
class MyAlloc
{

// Two Constructos which did nothing
public:


// Type Definitions

// Pointer to element type used in memory model
typedef T* pointer;
// Const Pointer to element type used in memory model
typedef const T* const_pointer;

// Reference  to element type used in memory model
typedef T& reference;
typedef const T& const_reference;

// Type of the element that is being used in the memory model
typedef T value_type;

// Rpresent largest object in allocator memory model
typedef size_t size_type; // Unsigned

// Represent two pointer in two allocator model
typedef ptrdiff_t difference_type; // Signed


// =================================================


// Member Function
/*
No throw is allowed for constructor
and destructor

C && D is trivial(Not important)


*/
MyAlloc();
/*
Copy C is need because exception
specification stated that constructor
is not allow to throw.

Does require operator= because
if (this != rhs) then code will not
be executed and Two MyAlloc object must
same which form by C++ standard allocator

*/
MyAlloc(const MyAlloc<T> &);
~MyAlloc();

/*
Require rebind because list(nodes), vector
(contigious)

Rebind is a structure that enables
an allocator for objects of one type
interpret as to allocate storage for
objects of another type.

To allocate objects of
different types than its
template parameter

The rebind member allows a container
to construct an allocator for some
arbitrary type out of the allocator type
provided as a template parameter.

This is the magic required
for std::list to work properly,
since given std::list<int>
( allocator<int>() ),
std::list actually needs to allocate memory
for Node<int>, and not int.
Thus, they need to rebind to


allocator<int>()::rebind<Node<int> >
::other instead.


For instance, the list container gets an
allocator<T> by default, but a list may
well need to allocate list_nodes as well
as T's. The container can construct an
allocator for list_nodes out of the
allocator for T's
(the template parameter,
Allocator, in this case) as follows:

Allocator::rebind<list_node>
::other list_node_allocator;

*/

/*
Explicit call by compiler is
allocator<T>::rebind<U>::other;

Here allocator client(vector, list)
request allocator type from allocator

Therefore, allocator using rebind to
preseve the old state type and duplicate
a same/new state type to pass to
allocator client.

Then, continue to class to rework a new
type which is
listAllocator < node<int> > and
not allocator<int>.


*/
template <class U>
struct rebind
{
typedef allocator<U> other;
}



// Return address of given object
pointer address(reference x) const;
const_pointer address(const_reference x) const;

//  Returns the largest value which can be passed to the 'allocate()'
function.
size_type MaxMemory();

/*
Returns storage for n elements of
the element type being used
in the memory model.

Elements will not be c
onstructed/initialized.

*/
pointer allocate(size_type);
/*
Deallocate element type used in
memory model begin at position p

Storage must be allocate by same allocator

Size must same in allocate()
p must not be 0.
Elements must have been destroyed before.
*/
void deallocate(pointer, size_type);

/*
Allocate must call before construct
This is a call to placement new
value is U
new((void*)p) T(u);
*/
void construct(pointer, const_reference);
/*
Destrory call ahead of (prior to) deallocate
new((void*)p) T(u);
*/
void destrory(pointer);
};

/*
No refernce type to void* -That's why need
specialization for void.
*/

// ================================================

template<class T1, class T2>
bool operator==(MyAlloc<T1>, MyAlloc<T2>) const
{
return MyAlloc<T1> == MyAlloc<T2>;
}

template<class T1, class T2>
bool operator!=(MyAlloc<T1>, MyAlloc<T2>) const
{
return MyAlloc<T1> != MyAlloc<T2>;
}

// ================================================



#endif

/*

allocate and deallocate function are
low level memory management which
doesn't participate in
object construction and destruction.

The purpose of the allocator is to allocate
raw memory without construction of objects,
as well as simply deallocate memory
without the need to destroy them.

Usage of ::operator new and ::operator delete
is preferred over keywords new and delete.

A* a = new A;
delete a;

Intepreted by compiler as below:

// assuming new throws std::bad_alloc upon failure

Allocate then construct
A* a = ::operator new(sizeof(A));
a->A::A();

if ( a != 0 )
{  // a check is necessary for delete

a->~A();
::operator delete(a);

Destroyed(Destruct) first
before deallocate
}


Every C++ standard like allocator must provide
these global operator== and operator!=

Memory Model are shared model, grabage collection,
segregrated model.

Why write custom allocators ?
1. To trace the memory operations of
your application to a file
2. Speed



Sample Override New and delete Code

void* operator new(size_t,void* anAddress)
{
return anAddress;
}
void* operator new(size_t size)
{
return Standard::Allocate(size);
}
void  operator delete(void *anAddress)
{
if (anAddress)
Standard::Free((Standard_Address&)anAddress);
}

The first new operator overload is for the
new with placement syntax, instead of
creating instances on the free store it
will use the address you provided.

This is useful for using preallocated memory (e.g. a buffer)
to store your objects and still have the
construtors and destructors called for these
objects.

Apparently this first overload is just the
default one that would be generated by
the compiler anyway.


The second new and the delete operator overload are apparently
defined because the coder wanted to use a custom allocator.
If the first new overload seems useless but is still present it may
be that the compiler is requiring it if you overload the new(size_t)
one ( just a guess), try removing the new(size_t, void*) definition
and see if the code still compiles and link.


No reference to object which allocated on the stack
This is make sense since stack unwinding
will get clean up and you will use danling
reference

Never pass auto_ptrs by value
if a function can throw


BTW, returning auto_ptrs by value is a
good idea for factory and
clone like functions.
*/







// Sketch version of list

/*
template <typename T, typename A>
class node
{
typedfed node list_nodes;

typename A::rebind<list_nodes>::others listNodeAllocator;
// Actually declare listNodeAllocator < list_nodes<T> >;

};

*/
Thanks for your correction.
Reply With Quote
  #3  
Old 08-14-2008, 03:39 AM
Ali Karaali
Guest
 
Default Re: General Allocator Regarding type definitions and void *specialized problem

You can not change or add code to std namespace because it is
undefined behaviour.
Reply With Quote
  #4  
Old 08-15-2008, 11:52 PM
PeterAPIIT@gmail.com
Guest
 
Default Re: General Allocator Regarding type definitions and void *specialized problem

I didn't add to code to namespace standard.


I create my custom allocator with my own namespace.

Please behave in C++ usenet community.

Thanks.
Reply With Quote
  #5  
Old 08-19-2008, 04:22 AM
PeterAPIIT@gmail.com
Guest
 
Default Re: General Allocator Regarding type definitions and void *specialized problem

Please help me.
Reply With Quote
  #6  
Old 08-26-2008, 01:40 AM
PeterAPIIT@gmail.com
Guest
 
Default Re: General Allocator Regarding type definitions and void *specialized problem

This is all my code.

Code:
#ifndef _Custom_Allocator_
#define _Custom_Allocator_

#include <memory>

using std::allocator;


// ================================================

template <class T>
class MyAllocator
{
public:

// Type Definitions

typedef T value_type;

typedef T* pointer;
typedef const T* const_pointer;

typedef T& reference;
typedef const T& const_reference;

typedef size_t size_type; // Unsigned

// Signed
typedef ptrdiff_t difference_type;


// Member Function

MyAllocator(){}

// MyAllocator(const MyAllocator<T> &rhs);
~MyAllocator(){}

// MyAllocator<T>::rebind<U>::other;
template <class U>
struct rebind
{
typedef MyAllocator<U> other;
}

pointer address(reference memory) const
{
return *memory;
}
const_pointer address(const_reference memory) const
{
return *memory;
}

size_type MaxMemory()
{
return ;
}

pointer allocate(size_type allocateSiZe)
{
return ::operator new (allocateSize);
}
void deallocate(pointer aPtr, size_type allocateSize)
{
if (aPtr != 0)
{
destrory(aPtr);
::operator delete aPtr[allocateSize];
}
}

void construct(pointer aPtr, const_reference value)
{
if (aPtr != 0)
{
// ((void *)aPtr) is placement new
// T(value) convert to T type
::operator new ((void *)aPtr) T(value);
}
}
void destrory(pointer aPtr)
{
if (aPtr != 0)
{
*aPtr = 0;
}
}


};

/*
No refernce type to void* -That's why need
specialization for void.
*/

// ==============  Global Functions  ===============

template<class T1, class T2>
bool operator==(MyAllocator<T1>, MyAllocator<T2>) const
{
return MyAllocator<T1> == MyAllocator<T2>;
}

template<class T1, class T2>
bool operator!=(MyAlloc<T1>, MyAlloc<T2>) const
{
return MyAllocator<T1> != MyAllocator<T2>;
}

// ================================================



#endif
What should i do for next steps ?

Thanks for your help.
Reply With Quote
  #7  
Old 08-26-2008, 02:00 AM
Alf P. Steinbach
Guest
 
Default Re: General Allocator Regarding type definitions and void * specializedproblem

* PeterAPIIT@gmail.com:
> This is all my code.


Uhm, please specify the problem in the article's text, not only in the subject line.

Subject line: "General Allocator Regarding type definitions and void *
specialized problem"

It would also be good with a little more detail about what the problem is. :-)



>
Code:
>
> #ifndef _Custom_Allocator_
> #define _Custom_Allocator_
Code:
Identifier starting with underscore followed by uppercase is reserved for the
implementation, don't use.

Also, preferentially use ALL UPPERCASE for macros (and generally not for other
identifiers, except where idiomatic such as T for template parameter).


> #include <memory>
>
> using std::allocator;

Don't use 'using' in a header file.

You're forcing client code to deal with name clashes.


> // ================================================
>
> template <class T>
> class MyAllocator
> {
> public:
>
> // Type Definitions
>
> 	typedef T value_type;
>
> 	typedef T* pointer;
> 	typedef const T* const_pointer;
>
> 	typedef T& reference;
> 	typedef const T& const_reference;
>
> 	typedef size_t size_type; // Unsigned
>
> 	// Signed
> 	typedef ptrdiff_t difference_type;
>
>
> // Member Function
>
> 	MyAllocator(){}
>
> 	// MyAllocator(const MyAllocator<T> &rhs);
> 	~MyAllocator(){}
>
> 	// MyAllocator<T>::rebind<U>::other;
> 	template <class U>
> 	struct rebind
> 	{
> 		typedef MyAllocator<U> other;
> 	}

Missing semicolon.

Which means: this is not your actual code.

At least not a version that you've managed to compile.


> 	pointer address(reference memory) const
> 	{
> 		return *memory;
> 	}

Invalid operation.

Which means: this is not your actual code.



> 	const_pointer address(const_reference memory) const
> 	{
> 		return *memory;
> 	}


Invalid operation.

Which means: this is not your actual code.


> 	size_type MaxMemory()
> 	{
> 		return ;
> 	}

Invalid operation.

Which means: this is not your actual code.



> 	pointer allocate(size_type allocateSiZe)
> 	{
> 		return ::operator new (allocateSize);
> 	}


Misspelled name.

Which means: this is not your actual code.


> 	void deallocate(pointer aPtr, size_type allocateSize)
> 	{
> 		if (aPtr != 0)
> 		{
> 			destrory(aPtr);
> 			::operator delete aPtr[allocateSize];
> 		}
> 	}

Misspelled name.

Which means: this is not your actual code.


> 	void construct(pointer aPtr, const_reference value)
> 	{
> 		if (aPtr != 0)
> 		{
> 			// ((void *)aPtr) is placement new
> 			// T(value) convert to T type
> 			::operator new ((void *)aPtr) T(value);
> 		}
> 	}

Invalid syntax.

Which means: this is not your actual code.


> 	void destrory(pointer aPtr)
> 	{
> 		if (aPtr != 0)
> 		{
> 			*aPtr = 0;
> 		}
> 	}

Misspelled name.

Which means: this is not your actual code.


>
>
> };
>
> /*
> 	No refernce type to void* -That's why need
> 	specialization for void.
> */
>
> // ==============  Global Functions  ===============
>
> template<class T1, class T2>
> bool operator==(MyAllocator<T1>, MyAllocator<T2>) const
> {
> 	return MyAllocator<T1> == MyAllocator<T2>;
> }

Invalid operation.

Which means: this is not your actual code.


> template<class T1, class T2>
> bool operator!=(MyAlloc<T1>, MyAlloc<T2>) const
> {
> 	return MyAllocator<T1> != MyAllocator<T2>;
> }

Invalid operation.

Which means: this is not your actual code.


> // ================================================
>
>
>
> #endif
>  

>
> What should i do for next steps ?


You should stop thinking about defining your own allocator.

Instead you should start with basics, learning C++ syntax and basic programming
(expressions, loops, decisions, routines). A good C++ textbook will help with
that. E.g. Glasborrow's "You can do it!", or, if you already know some
programming (perhaps in some other language), "Accelerated C++".

And when you run into some problem then, please post actual code that compiles.


Cheers & hth.,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Reply With Quote
  #8  
Old 09-02-2008, 03:36 AM
PeterAPIIT@gmail.com
Guest
 
Default Re: General Allocator Regarding type definitions and void *specialized problem

I have corrected my code.

Now my problem is this:

Quote:
Error 1 error C2440: 'default argument' : cannot convert from
'MyAllocator<T>' to 'MyAllocator<T>' c:\program files\microsoft visual
studio 8\vc\include\list 83
Code:
#ifndef Custom_Allocator
#define Custom_Allocator


template <class T>
class MyAllocator
{
public:

// Type Definitions

typedef T value_type;

typedef T* pointer;
typedef const T* const_pointer;

typedef T& reference;
typedef const T& const_reference;

typedef size_t size_type; // Unsigned

// Signed
typedef ptrdiff_t difference_type;


// Member Function

MyAllocator(){}

template <class U>
MyAllocator(const MyAllocator<T> &rhs){}

~MyAllocator(){}

// MyAllocator<T>::rebind<U>::other;
template <class U>
struct rebind
{
typedef MyAllocator<U> other;
};

pointer address(reference memory) const
{
return &memory;
}
const_pointer address(const_reference memory) const
{
return &memory;
}

size_type max_size() const
{
return size_t(+99);
}

pointer allocate(size_type allocateSize)
{
return static_cast<pointer> (::operator new (allocateSize));
}

void deallocate(pointer aPtr, size_type allocateSize)
{
if (aPtr != 0)
{
destroy(aPtr);
::operator delete aPtr[allocateSize];
}
}

void construct(pointer aPtr, const_reference value)
{
if (aPtr != 0)
{
// ((void *)aPtr) is placement new
// T(value) convert to T type
::operator new ((void *)aPtr) T(value);
}
}
void destroy(pointer aPtr)
{
if (aPtr != 0)
{
aPtr->~MyAllocator<T>;
}
}



};

/*
No refernce type to void* -That's why need
specialization for void.
*/

// ==============  Global Functions  ===============

// Non member function cannot declare as constant
template<class T1, class T2>
bool operator==(MyAllocator<T1>& first, MyAllocator<T2>& second)
{
return first == second;
}

template<class T1, class T2>
bool operator!=(MyAllocator<T1>& first, MyAllocator<T2>& second)
{
return first!=second;
}
Please help me.
Reply With Quote
  #9  
Old 09-02-2008, 11:05 PM
PeterAPIIT@gmail.com
Guest
 
Default Re: General Allocator Regarding type definitions and void *specialized problem

Code:


#ifndef Custom_Allocator
#define Custom_Allocator



template <class T>
class MyAllocator
{
public:

// Type Definitions

typedef T value_type;

typedef T* pointer;
typedef const T* const_pointer;

typedef T& reference;
typedef const T& const_reference;

typedef size_t size_type; // Unsigned

// Signed
typedef ptrdiff_t difference_type;


// Member Function

MyAllocator(){}

template <class U>
MyAllocator(const MyAllocator<T> &rhs){}

~MyAllocator(){}

// MyAllocator<T>::rebind<U>::other;
template <class U>
struct rebind
{
typedef MyAllocator<U> other;
};

pointer address(reference memory) const
{
return &memory;
}
const_pointer address(const_reference memory) const
{
return &memory;
}

size_type max_size() const
{
return size_t(+99);
}

pointer allocate(size_type allocateSize)
{
return static_cast<pointer> (::operator new (allocateSize));
}

void deallocate(pointer aPtr, size_type allocateSize)
{
if (aPtr != 0)
{
destroy(aPtr);
//		::operator delete aPtr[allocateSize];
}
}

void construct(pointer aPtr, const_reference value)
{
if (aPtr != 0)
{
// ((void *)aPtr) is placement new
// T(value) convert to T type
::operator new ((void *)aPtr) T(value);
}
}
void destroy(pointer aPtr)
{
if (aPtr != 0)
{
//			aPtr->~MyAllocator<T>;
}
}
};

/*
No refernce type to void* -That's why need
specialization for void.
*/

// ==============  Global Functions  ===============

// Non member function cannot declare as constant
template<class T1, class T2>
bool operator==(MyAllocator<T1>& first, MyAllocator<T2>& second)
{
return first == second;
}

template<class T1, class T2>
bool operator!=(MyAllocator<T1>& first, MyAllocator<T2>& second)
{
return first!=second;
}
This is my code so far.
Reply With Quote
  #10  
Old 09-04-2008, 09:31 AM
PeterAPIIT@gmail.com
Guest
 
Default Re: General Allocator Regarding type definitions and void *specialized problem


Please help me.
Reply With Quote
Reply


Thread Tools
Display Modes


All times are GMT -5. The time now is 07:22 AM.


Powered by vBulletin® Version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
vB Ad Management by =RedTyger=

In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.