Index: doc/user/user.tex
===================================================================
--- doc/user/user.tex	(revision 9c6f459404ce3627bd0c5f7bbf944db4b7c0feda)
+++ doc/user/user.tex	(revision 6b4a1bf2d9a50aacfffe4d6ad5ebea86eed32b43)
@@ -11,6 +11,6 @@
 %% Created On       : Wed Apr  6 14:53:29 2016
 %% Last Modified By : Peter A. Buhr
-%% Last Modified On : Thu Mar  5 12:09:42 2020
-%% Update Count     : 3885
+%% Last Modified On : Fri Mar  6 13:34:52 2020
+%% Update Count     : 3924
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
@@ -6621,7 +6621,8 @@
 An array may be filled, resized, or aligned.
 \end{description}
-\VRef[Table]{t:AllocationVersusCapabilities} shows allocation routines supporting different combinations of storage-management capabilities:
+\VRef[Table]{t:AllocationVersusCapabilities} shows allocation routines supporting different combinations of storage-management capabilities.
 \begin{table}
 \centering
+\begin{minipage}{0.75\textwidth}
 \begin{tabular}{@{}r|l|l|l|l|l@{}}
 \multicolumn{1}{c}{}&		& \multicolumn{1}{c|}{fill}	& resize	& alignment	& array	\\
@@ -6631,19 +6632,39 @@
 		& ©realloc©			& copy			& yes		& no		& no	\\
 		& ©memalign©		& no			& no		& yes		& no	\\
-		& ©aligned_alloc©	& no			& no		& yes		& no	\\
+		& ©aligned_alloc©\footnote{Same as ©memalign© but size is an integral multiple of alignment, which is universally ignored.}
+							& no			& no		& yes		& no	\\
 		& ©posix_memalign©	& no			& no		& yes		& no	\\
+		& ©valloc©			& no			& no		& yes (page size)& no	\\
+		& ©pvalloc©\footnote{Same as ©valloc© but rounds size to multiple of page size.}
+							& no			& no		& yes (page size)& no	\\
 \hline
 \CFA	& ©cmemalign©		& yes (0 only)	& no		& yes		& yes	\\
 		& ©realloc©			& copy			& yes		& yes		& no	\\
-		& ©alloc©			& no			& no		& no		& no	\\
-		& ©alloc©			& copy			& no/yes	& no		& yes	\\
-		& ©alloc©			& no/copy/yes	& no/yes	& no		& yes	\\
-		& ©alloc_set©		& no/yes		& no		& yes		& yes	\\
-		& ©alloc_align©		& no/yes		& no		& yes		& yes	\\
-		& ©alloc_align_set©	& no/yes		& no		& yes		& yes	\\
+		& ©alloc©			& no			& yes		& no		& yes	\\
+		& ©alloc_set©		& yes			& yes		& no		& yes	\\
+		& ©alloc_align©		& no			& yes		& yes		& yes	\\
+		& ©alloc_align_set©	& yes			& yes		& yes		& yes	\\
 \end{tabular}
+\end{minipage}
 \caption{Allocation Routines versus Storage-Management Capabilities}
 \label{t:AllocationVersusCapabilities}
 \end{table}
+
+\CFA memory management extends the type safety of all allocations by using the type of the left-hand-side type to determine the allocation size and return a matching type for the new storage.
+Type-safe allocation is provided for all C allocation routines and new \CFA allocation routines, \eg in
+\begin{cfa}
+int * ip = (int *)malloc( sizeof(int) );		§\C{// C}§
+int * ip = malloc();							§\C{// \CFA type-safe version of C malloc}§
+int * ip = alloc();								§\C{// \CFA type-safe uniform alloc}§
+\end{cfa}
+the latter two allocations determine the allocation size from the type of ©p© (©int©) and cast the pointer to the allocated storage to ©int *©.
+
+\CFA memory management extends allocation safety by implicitly honouring all alignment requirements, \eg in
+\begin{cfa}
+struct S { int i; } __attribute__(( aligned( 128 ) )); // cache-line alignment
+S * sp = malloc();								§\C{// honour type alignment}§
+\end{cfa}
+the storage allocation is implicitly aligned to 128 rather than the default 16.
+The alignment check is performed at compile time so there is no runtime cost.
 
 \CFA memory management extends the resize capability with the notion of \newterm{sticky properties}.
@@ -6652,4 +6673,21 @@
 Without sticky properties it is dangerous to use ©realloc©, resulting in an idiom of manually performing the reallocation to maintain correctness.
 
+\CFA memory management extends allocation to support constructors for initialization of allocated storage, \eg in
+\begin{cfa}
+struct S { int i; };							§\C{// cache-line aglinment}§
+void ?{}( S & s, int i ) { s.i = i; }
+// assume ?|? operator for printing an S
+
+S & sp = *®new®( 3 );							§\C{// call constructor after allocation}§
+sout | sp.i;
+®delete®( &sp );
+
+S * spa = ®anew®( 10, 5 );						§\C{// allocate array and initialize each array element}§
+for ( i; 10 ) sout | spa[i] | nonl;
+sout | nl;
+®adelete®( 10, spa );
+\end{cfa}
+Allocation routines ©new©/©anew© allocate a variable/array and initialize storage using the allocated type's constructor.
+Note, the matching deallocation routines ©delete©/©adelete©.
 
 \leavevmode
Index: libcfa/src/heap.cfa
===================================================================
--- libcfa/src/heap.cfa	(revision 9c6f459404ce3627bd0c5f7bbf944db4b7c0feda)
+++ libcfa/src/heap.cfa	(revision 6b4a1bf2d9a50aacfffe4d6ad5ebea86eed32b43)
@@ -10,6 +10,6 @@
 // Created On       : Tue Dec 19 21:58:35 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Feb  4 10:04:51 2020
-// Update Count     : 648
+// Last Modified On : Fri Mar  6 10:14:52 2020
+// Update Count     : 650
 //
 
@@ -819,7 +819,6 @@
 
 extern "C" {
-	// The malloc() function allocates size bytes and returns a pointer to the allocated memory. The memory is not
-	// initialized. If size is 0, then malloc() returns either 0p, or a unique pointer value that can later be
-	// successfully passed to free().
+	// Allocates size bytes and returns a pointer to the allocated memory. The memory is not initialized. If size is 0,
+	// then malloc() returns either 0p, or a unique pointer value that can later be successfully passed to free().
 	void * malloc( size_t size ) {
 		#ifdef __STATISTICS__
@@ -831,7 +830,7 @@
 	} // malloc
 
-	// The calloc() function allocates memory for an array of nmemb elements of size bytes each and returns a pointer to
-	// the allocated memory. The memory is set to zero. If nmemb or size is 0, then calloc() returns either 0p, or a
-	// unique pointer value that can later be successfully passed to free().
+	// Allocate memory for an array of nmemb elements of size bytes each and returns a pointer to the allocated
+	// memory. The memory is set to zero. If nmemb or size is 0, then calloc() returns either 0p, or a unique pointer
+	// value that can later be successfully passed to free().
 	void * calloc( size_t noOfElems, size_t elemSize ) {
 		#ifdef __STATISTICS__
@@ -843,10 +842,10 @@
 	} // calloc
 
-	// The realloc() function changes the size of the memory block pointed to by ptr to size bytes. The contents will be
-	// unchanged in the range from the start of the region up to the minimum of the old and new sizes. If the new size
-	// is larger than the old size, the added memory will not be initialized.  If ptr is 0p, then the call is
-	// equivalent to malloc(size), for all values of size; if size is equal to zero, and ptr is not 0p, then the call
-	// is equivalent to free(ptr). Unless ptr is 0p, it must have been returned by an earlier call to malloc(),
-	// calloc() or realloc(). If the area pointed to was moved, a free(ptr) is done.
+	// Change the size of the memory block pointed to by ptr to size bytes. The contents shall be unchanged in the range
+	// from the start of the region up to the minimum of the old and new sizes. If the new size is larger than the old
+	// size, the added memory shall not be initialized.  If ptr is 0p, then the call is equivalent to malloc(size), for
+	// all values of size; if size is equal to zero, and ptr is not 0p, then the call is equivalent to free(ptr). Unless
+	// ptr is 0p, it must have been returned by an earlier call to malloc(), calloc() or realloc(). If the area pointed
+	// to was moved, a free(ptr) is done.
 	void * realloc( void * oaddr, size_t size ) {
 		#ifdef __STATISTICS__
@@ -903,6 +902,6 @@
 	} // realloc
 
-	// The obsolete function memalign() allocates size bytes and returns a pointer to the allocated memory. The memory
-	// address will be a multiple of alignment, which must be a power of two.
+	// Allocates size bytes and returns a pointer to the allocated memory. The memory address shall be a multiple of
+	// alignment, which must be a power of two. (obsolete)
 	void * memalign( size_t alignment, size_t size ) {
 		#ifdef __STATISTICS__
@@ -915,5 +914,5 @@
 
 
-	// The cmemalign() function is the same as calloc() with memory alignment.
+	// Same as calloc() with memory alignment.
 	void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ) {
 		#ifdef __STATISTICS__
@@ -925,6 +924,6 @@
 	} // cmemalign
 
-	// The function aligned_alloc() is the same as memalign(), except for the added restriction that size should be a
-	// multiple of alignment.
+	// Same as memalign(), but ISO/IEC 2011 C11 Section 7.22.2 states: the value of size shall be an integral multiple
+    // of alignment. This requirement is universally ignored.
 	void * aligned_alloc( size_t alignment, size_t size ) {
 		return memalign( alignment, size );
@@ -932,8 +931,8 @@
 
 
-	// The function posix_memalign() allocates size bytes and places the address of the allocated memory in *memptr. The
-	// address of the allocated memory will be a multiple of alignment, which must be a power of two and a multiple of
-	// sizeof(void *). If size is 0, then posix_memalign() returns either 0p, or a unique pointer value that can later
-	// be successfully passed to free(3).
+	// Allocates size bytes and places the address of the allocated memory in *memptr. The address of the allocated
+	// memory shall be a multiple of alignment, which must be a power of two and a multiple of sizeof(void *). If size
+	// is 0, then posix_memalign() returns either 0p, or a unique pointer value that can later be successfully passed to
+	// free(3).
 	int posix_memalign( void ** memptr, size_t alignment, size_t size ) {
 	  if ( alignment < sizeof(void *) || ! libPow2( alignment ) ) return EINVAL; // check alignment
@@ -943,6 +942,6 @@
 	} // posix_memalign
 
-	// The obsolete function valloc() allocates size bytes and returns a pointer to the allocated memory. The memory
-	// address will be a multiple of the page size.  It is equivalent to memalign(sysconf(_SC_PAGESIZE),size).
+	// Allocates size bytes and returns a pointer to the allocated memory. The memory address shall be a multiple of the
+	// page size.  It is equivalent to memalign(sysconf(_SC_PAGESIZE),size).
 	void * valloc( size_t size ) {
 		return memalign( pageSize, size );
@@ -950,7 +949,13 @@
 
 
-	// The free() function frees the memory space pointed to by ptr, which must have been returned by a previous call to
-	// malloc(), calloc() or realloc().  Otherwise, or if free(ptr) has already been called before, undefined behavior
-	// occurs. If ptr is 0p, no operation is performed.
+	// Same as valloc but rounds size to multiple of page size.
+	void * pvalloc( size_t size ) {
+		return memalign( pageSize, libCeiling( size, pageSize ) );
+	} // pvalloc
+
+
+	// Frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc()
+	// or realloc().  Otherwise, or if free(ptr) has already been called before, undefined behavior occurs. If ptr is
+	// 0p, no operation is performed.
 	void free( void * addr ) {
 		#ifdef __STATISTICS__
@@ -973,5 +978,5 @@
 
 
-	// The malloc_alignment() function returns the alignment of the allocation.
+	// Returns the alignment of the allocation.
 	size_t malloc_alignment( void * addr ) {
 	  if ( unlikely( addr == 0p ) ) return libAlign();	// minimum alignment
@@ -985,5 +990,5 @@
 
 
-	// The malloc_zero_fill() function returns true if the allocation is zero filled, i.e., initially allocated by calloc().
+	// Returns true if the allocation is zero filled, i.e., initially allocated by calloc().
 	bool malloc_zero_fill( void * addr ) {
 	  if ( unlikely( addr == 0p ) ) return false;		// null allocation is not zero fill
@@ -996,6 +1001,6 @@
 
 
-	// The malloc_usable_size() function returns the number of usable bytes in the block pointed to by ptr, a pointer to
-	// a block of memory allocated by malloc(3) or a related function.
+	// Returns the number of usable bytes in the block pointed to by ptr, a pointer to a block of memory allocated by
+	// malloc or a related function.
 	size_t malloc_usable_size( void * addr ) {
 	  if ( unlikely( addr == 0p ) ) return 0;			// null allocation has 0 size
@@ -1009,6 +1014,5 @@
 
 
-	// The malloc_stats() function prints (on default standard error) statistics about memory allocated by malloc(3) and
-	// related functions.
+	// Prints (on default standard error) statistics about memory allocated by malloc and related functions.
 	void malloc_stats( void ) {
 		#ifdef __STATISTICS__
@@ -1018,5 +1022,5 @@
 	} // malloc_stats
 
-	// The malloc_stats_fd() function changes the file descripter where malloc_stats() writes the statistics.
+	// Changes the file descripter where malloc_stats() writes statistics.
 	int malloc_stats_fd( int fd __attribute__(( unused )) ) {
 		#ifdef __STATISTICS__
@@ -1030,7 +1034,6 @@
 
 
-	// The mallopt() function adjusts parameters that control the behavior of the memory-allocation functions (see
-	// malloc(3)). The param argument specifies the parameter to be modified, and value specifies the new value for that
-	// parameter.
+	// Adjusts parameters that control the behavior of the memory-allocation functions (see malloc). The param argument
+	// specifies the parameter to be modified, and value specifies the new value for that parameter.
 	int mallopt( int option, int value ) {
 		choose( option ) {
@@ -1043,6 +1046,5 @@
 	} // mallopt
 
-	// The malloc_trim() function attempts to release free memory at the top of the heap (by calling sbrk(2) with a
-	// suitable argument).
+	// Attempt to release free memory at the top of the heap (by calling sbrk with a suitable argument).
 	int malloc_trim( size_t ) {
 		return 0;										// => impossible to release memory
@@ -1050,7 +1052,7 @@
 
 
-	// The malloc_info() function exports an XML string that describes the current state of the memory-allocation
-	// implementation in the caller.  The string is printed on the file stream stream.  The exported string includes
-	// information about all arenas (see malloc(3)).
+	// Exports an XML string that describes the current state of the memory-allocation implementation in the caller.
+	// The string is printed on the file stream stream.  The exported string includes information about all arenas (see
+	// malloc).
 	int malloc_info( int options, FILE * stream ) {
 		if ( options != 0 ) { errno = EINVAL; return -1; }
@@ -1059,8 +1061,8 @@
 
 
-	// The malloc_get_state() function records the current state of all malloc(3) internal bookkeeping variables (but
-	// not the actual contents of the heap or the state of malloc_hook(3) functions pointers).  The state is recorded in
-	// a system-dependent opaque data structure dynamically allocated via malloc(3), and a pointer to that data
-	// structure is returned as the function result.  (It is the caller's responsibility to free(3) this memory.)
+	// Records the current state of all malloc internal bookkeeping variables (but not the actual contents of the heap
+	// or the state of malloc_hook functions pointers).  The state is recorded in a system-dependent opaque data
+	// structure dynamically allocated via malloc, and a pointer to that data structure is returned as the function
+	// result.  (The caller must free this memory.)
 	void * malloc_get_state( void ) {
 		return 0p;										// unsupported
@@ -1068,6 +1070,6 @@
 
 
-	// The malloc_set_state() function restores the state of all malloc(3) internal bookkeeping variables to the values
-	// recorded in the opaque data structure pointed to by state.
+	// Restores the state of all malloc internal bookkeeping variables to the values recorded in the opaque data
+	// structure pointed to by state.
 	int malloc_set_state( void * ptr ) {
 		return 0;										// unsupported
Index: libcfa/src/stdlib.hfa
===================================================================
--- libcfa/src/stdlib.hfa	(revision 9c6f459404ce3627bd0c5f7bbf944db4b7c0feda)
+++ libcfa/src/stdlib.hfa	(revision 6b4a1bf2d9a50aacfffe4d6ad5ebea86eed32b43)
@@ -10,6 +10,6 @@
 // Created On       : Thu Jan 28 17:12:35 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Feb  4 08:27:01 2020
-// Update Count     : 401
+// Last Modified On : Thu Mar  5 11:29:06 2020
+// Update Count     : 407
 //
 
@@ -21,9 +21,10 @@
 #include <stdlib.h>										// *alloc, strto*, ato*
 
+// Reduce includes by explicitly defining these routines.
 extern "C" {
 	void * memalign( size_t align, size_t size );		// malloc.h
+    void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ); // CFA heap
 	void * memset( void * dest, int fill, size_t size ); // string.h
 	void * memcpy( void * dest, const void * src, size_t size ); // string.h
-    void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ); // CFA heap
 } // extern "C"
 
@@ -40,5 +41,5 @@
 
 static inline forall( dtype T | sized(T) ) {
-	// C dynamic allocation
+	// Cforall safe equivalents, i.e., implicit size specification
 
 	T * malloc( void ) {
@@ -72,5 +73,5 @@
 	} // posix_memalign
 
-	// Cforall dynamic allocation
+	// Cforall safe general allocation, fill, resize, array
 
 	T * alloc( void ) {
@@ -159,5 +160,5 @@
 
 static inline forall( dtype T | sized(T) ) {
-	// data, non-array types
+	// Cforall safe initialization/copy, i.e., implicit size specification, non-array types
 	T * memset( T * dest, char fill ) {
 		return (T *)memset( dest, fill, sizeof(T) );
@@ -170,5 +171,5 @@
 
 static inline forall( dtype T | sized(T) ) {
-	// data, array types
+	// Cforall safe initialization/copy, i.e., implicit size specification, array types
 	T * amemset( T dest[], char fill, size_t dim ) {
 		return (T *)(void *)memset( dest, fill, dim * sizeof(T) ); // C memset
@@ -180,10 +181,10 @@
 } // distribution
 
-// allocation/deallocation and constructor/destructor, non-array types
+// Cforall allocation/deallocation and constructor/destructor, non-array types
 forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * new( Params p );
 forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void delete( T * ptr );
 forall( dtype T, ttype Params | sized(T) | { void ^?{}( T & ); void delete( Params ); } ) void delete( T * ptr, Params rest );
 
-// allocation/deallocation and constructor/destructor, array types
+// Cforall allocation/deallocation and constructor/destructor, array types
 forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * anew( size_t dim, Params p );
 forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void adelete( size_t dim, T arr[] );
