B.3.1 The Package Interfaces.C.Strings
The package Interfaces.C.Strings declares types and 
subprograms allowing an Ada program to allocate, reference, update, and 
free C-style strings. In particular, the private type chars_ptr corresponds 
to a common use of “char *” in C programs, and an object 
of this type can be passed to a subprogram to which with Import 
=> True, Convention => C has been specified, and for which 
“char *” is the type of the argument of the C function. 
Static Semantics
The library package 
Interfaces.C.Strings has the following declaration: 
package Interfaces.C.Strings 
is
   pragma Preelaborate(Strings);
 
   type char_array_access 
is access all char_array;
 
   type chars_ptr 
is private;
   
pragma Preelaborable_Initialization(chars_ptr);
 
   type chars_ptr_array 
is array (size_t 
range <>) 
of aliased chars_ptr;
 
   Null_Ptr : 
constant chars_ptr;
 
   function To_Chars_Ptr (Item      : 
in char_array_access;
                          Nul_Check : 
in Boolean := False)
      
return chars_ptr;
 
   function New_Char_Array (Chars   : 
in char_array) 
return chars_ptr;
 
   function New_String (Str : 
in String) 
return chars_ptr;
 
   procedure Free (Item : 
in out chars_ptr);
 
   Dereference_Error : 
exception;
 
   function Value (Item : 
in chars_ptr) 
return char_array;
 
   function Value (Item : 
in chars_ptr; Length : 
in size_t)
      
return char_array;
 
   function Value (Item : 
in chars_ptr) 
return String;
 
   function Value (Item : 
in chars_ptr; Length : 
in size_t)
      
return String;
 
   function Strlen (Item : 
in chars_ptr) 
return size_t;
 
   procedure Update (Item   : 
in chars_ptr;
                     Offset : 
in size_t;
                     Chars  : 
in char_array;
                     Check  : 
in Boolean := True);
 
   procedure Update (Item   : 
in chars_ptr;
                     Offset : 
in size_t;
                     Str    : 
in String;
                     Check  : 
in Boolean := True);
 
   Update_Error : 
exception;
 
private
   ... -- not specified by the language
end Interfaces.C.Strings;
The type chars_ptr is C-compatible and corresponds 
to the use of C's “char *” for a pointer to the first char 
in a char array terminated by nul. When an object of type chars_ptr is 
declared, its value is by default set to Null_Ptr, unless the object 
is imported (see 
B.1). 
 
function To_Chars_Ptr (Item      : in char_array_access;
                       Nul_Check : in Boolean := False)
   return chars_ptr;
If Item is null, 
then To_Chars_Ptr returns Null_Ptr. If Item is not null, Nul_Check 
is True, and Item.all does not contain nul, then the function 
propagates Terminator_Error; otherwise, To_Chars_Ptr performs a pointer 
conversion with no allocation of memory.
function New_Char_Array (Chars   : in char_array) return chars_ptr;
This function returns a pointer to an allocated 
object initialized to Chars(Chars'First .. Index) & nul, where 
Index = Chars'Last if Chars does not contain 
nul, or
Index is the smallest size_t value I such 
that Chars(I+1) = nul. 
Storage_Error is 
propagated if the allocation fails.
function New_String (Str : in String) return chars_ptr;
This function is 
equivalent to New_Char_Array(To_C(Str)).
procedure Free (Item : in out chars_ptr);
If Item is Null_Ptr, 
then Free has no effect. Otherwise, Free releases the storage occupied 
by Value(Item), and resets Item to Null_Ptr.
function Value (Item : in chars_ptr) return char_array;
If Item = Null_Ptr, 
then Value propagates Dereference_Error. Otherwise, Value returns the 
prefix of the array of chars pointed to by Item, up to and including 
the first nul. The lower bound of the result is 0. If Item does not point 
to a nul-terminated string, then execution of Value is erroneous.
function Value (Item : in chars_ptr; Length : in size_t)
   return char_array;
If Item = Null_Ptr, 
then Value propagates Dereference_Error. Otherwise, Value returns the 
shorter of two arrays, either the first Length chars pointed to by Item, 
or Value(Item). The lower bound of the result is 0. If Length is 0, then 
Value propagates Constraint_Error. 
function Value (Item : in chars_ptr) return String;
Equivalent to To_Ada(Value(Item), 
Trim_Nul=>True).
function Value (Item : in chars_ptr; Length : in size_t)
   return String;
Equivalent to To_Ada(Value(Item, 
Length) & nul, Trim_Nul=>True).
function Strlen (Item : in chars_ptr) return size_t;
Returns Val'Length–1 
where Val = Value(Item); propagates Dereference_Error if Item 
= Null_Ptr. 
procedure Update (Item   : in chars_ptr;
                  Offset : in size_t;
                  Chars  : in char_array;
                  Check  : Boolean := True);
If Item = Null_Ptr, 
then Update propagates Dereference_Error. Otherwise, this procedure updates 
the value pointed to by Item, starting at position Offset, using Chars 
as the data to be copied into the array. Overwriting the nul terminator, 
and skipping with the Offset past the nul terminator, are both prevented 
if Check is True, as follows: 
Let N = Strlen(Item). If Check is True, 
then: 
If Offset+Chars'Length>N, propagate 
Update_Error.
Otherwise, overwrite the data in 
the array pointed to by Item, starting at the char at position Offset, 
with the data in Chars. 
If Check 
is False, then processing is as above, but with no check that Offset+Chars'Length>N. 
procedure Update (Item   : in chars_ptr;
                  Offset : in size_t;
                  Str    : in String;
                  Check  : in Boolean := True);
Equivalent to Update(Item, Offset, To_C(Str, Append_Nul 
=> False), Check). 
Erroneous Execution
Execution of any of the following 
is erroneous if the Item parameter is not null_ptr and Item does not 
point to a nul-terminated array of chars. 
 
a Value function not taking a Length parameter,
the Free procedure,
the Strlen function. 
Execution of Free(X) is also 
erroneous if the chars_ptr X was not returned by New_Char_Array or New_String.
 
Reading or updating a freed char_array 
is erroneous.
 
Execution of Update is erroneous 
if Check is False and a call with Check equal to True would have propagated 
Update_Error. 
 
9  New_Char_Array and New_String might be 
implemented either through the allocation function from the C environment 
(“malloc”) or through Ada dynamic memory allocation (“new”). 
The key points are 
the returned value (a chars_ptr) 
is represented as a C “char *” so that it may be passed to 
C functions;
the allocated object should be freed 
by the programmer via a call of Free, not by a called C function. 
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe