Pascal. Delphi. Implementation of strings of type PChar in computer memory. Types PAnsiChar, PWideChar

Implementation of strings of type PChar in computer memory. Types PAnsiChar, PWideChar. Memory allocation for strings. Access by index


Contents


Search other resources:

1. Representation of ASCIIZ strings in Pascal. PChar, PAnsiChar, PWideChar types

In addition to the standard representation using the String type, strings in Pascal can be represented by the PChar, PANsiChar, and PWideChar types. These types define so-called ASCIIZ strings. Each ASCIIZ string is terminated by a special null character (null terminator), denoted as ‘\0’ in C-oriented languages or #0 in Pascal.

Figure 1 shows the representation of the ASCIIZ string in the computer’s memory.

Representation of an ASCIIZ string in computer memory

Figure 1. Representation of an ASCIIZ string in computer memory

The PChar type describes a pointer to a Char type

type
  PChar = ^Char;

A modification of the PChar type is the PANsiChar and PWideChar types, which are pointers according to the AnsiChar and WideChar types. More details about character types in Free Pascal and Delphi are described here.

 

2. Functions for working with PChar, PAnsiChar, PWideChar types. The list

The following functions are used to work with strings of the PChar type:

  • StrCat, StrLCat – implements string concatenation;
  • StrComp, StrIComp, StrLComp, StrLIComp – compare two strings;
  • StrCopy, StrECopy, StrLCopy – copy the values of one string to another;
  • StrDispose – destroys the string and the memory previously allocated for it;
  • StrEnd – returns a pointer to the character terminating the string;
  • StrLen – returns the length of the string;
  • StrLower – converts a string to lower case;
  • StrMove – moves one string to the place of another string;
  • StrNew – allocates memory for the new string;
  • StrPas – converts a string of PChar type to a string of String type;
  • StrPCopy – copies a string of type String to a string of type PChar;
  • StrPos – finds a substring in a string;
  • StrRScan, StrScan – finds the position of the specified character in a string;
  • StrUpper – converts a string to uppercase and returns a pointer to it.

 

3. Memory allocation for PAnsiChar, PWideChar type strings. Functions AnsiStrAlloc, WideStrAlloc

In order to use strings like PANsiChar, PWideChar for them, you must first allocate the necessary memory fragment. The following functions are used to allocate memory

function AnsiStrAlloc(Size: Cardinal): PAnsiChar;
function WideStrAlloc(Size: Cardinal): PWideChar;

here

  • Size – string size in characters. For PAnsiChar strings, each character is 1 byte. For strings of type PWideChar, each character occupies 2 bytes (Unicode encoding).

Example.

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  ps1 : PAnsiChar;
  ps2 : PWideChar;
  s : string;

begin
  // Function AnsiStrAlloc, WideStrAlloc.
  // Demonstrates entering a string from the console keyboard
  // and copy this string to AnsiStrAlloc, WideStrAlloc types

  // 1. Enter a string of type String from the keyboard
  Write('s = ');
  Readln(s);

  // 2. Function AnsiStrAlloc
  // 2.1. Allocate memory for PANsiChar string,
  // the memory size is equal to the size of the string s
  ps1 := AnsiStrAlloc(Length(s));

  // 2.2. Copy string s => ps1
  StrPCopy(ps1, s);

  // 2.3. Display ps1
  Writeln('ps1 = ', ps1);

  // 3. Function WideStrAlloc
  // 3.1. Allocate memory for PWideChar string
  ps2 := WideStrAlloc(Length(s));

  // 3.2. Copy s => ps2
  StrPCopy(ps2, s);

  // 3.3. Display ps2
  Writeln('ps2 = ', ps2);

  Readln;
end.

Result

s = abcdef
ps1 = abcdef
ps2 = abcdef

 

4. Access to a single character in a string of type PChar, PAnsiChar, PWideChar. Index access operation []

For strings of PChar, PANsiChar, and PWideChar types, it is possible to access a given character using the [] indexing operation. In general, accessing an element of a string looks like this:

S[index]

here

  • S – string of type PChar, PAnsiChar, PWideChar;
  • index – character position that starts at 0.

Individual characters of strings like PChar, PANsiChar, PWideChar can be changed. This means that the index access operator [] can be used both in an expression and on the left side of the assignment operator.

Example.

In the example, using index access, the creation of a string of type PAnsiChar and PWideChar is implemented.

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  ps1 : PAnsiChar;
  ps2 : PWideChar;
  i : Integer;
  s : string;

begin
  // Access by index []

  // 1. Create the AnsiChar string
  // 1.1. Allocate memory for string
  ps1 := AnsiStrAlloc(10);

  // 1.2. Write the 'Hello!' word to string ps1
  ps1[0] := 'H';
  ps1[1] := 'e';
  ps1[2] := 'l';
  ps1[3] := 'l';
  ps1[4] := 'o';
  ps1[5] := '!';
  ps1[6] := #0; // end of line character

  // 1.3. Display the string
  Write('ps1 = ');
  for i := 0 to StrLen(ps1) do
    Write(ps1[i]);
  Writeln;

  // 2. Create a string of WideChar type
  // 2.1. Allocate memory for string
  ps2 := WideStrAlloc(15);

  // 2.2. Write the word 'BestProg' to ps2 string
  ps2[0] := 'B';
  ps2[1] := 'e';
  ps2[2] := 's';
  ps2[3] := 't';
  ps2[4] := 'P';
  ps2[5] := 'r';
  ps2[6] := 'o';
  ps2[7] := 'g';
  ps2[8] := #0; // end of line

  // 2.3. Display the string
  Writeln('ps2 = ', StrPas(ps2));

  // 2.4. Add the '.net' to string
  ps2[8] := '.';
  ps2[9] := 'n';
  ps2[10] := 'e';
  ps2[11] := 't';
  ps2[12] := #0;

  // 2.5. Change 'B'->'b', 'P'->'p'
  ps2[0] := 'b';
  ps2[4] := 'p';

  // 2.6. Display ps2 to screen
  Writeln('ps2 = ', StrPas(ps2));

  Readln;
end.

Result

ps1 = Hello!
ps2 = BestProg
ps2 = bestprog.net

 

5. Function StrNew and procedure StrDispose. Memory allocation and deallocation for PAnsiChar and PWideChar strings

To work with strings of the PChar, PAnsiChar and PWideChar types, the mandatory operations are allocating and freeing memory in the dynamic area. To perform these operations, the StrNew and StrDispose functions are used.

The StrNew function creates a new string based on an existing one and contains the following declarations for the PAnsiChar and PWideChar types

function StrNew(const Str: PAnsiChar): PAnsiChar;
function StrNew(const Str: PWideChar): PWideChar;

here

  • Str – a constant string for which memory is allocated.

After you finish working with a string (at the end of a program, procedure, or some function), you need to free the memory allocated for this string. The procedure StrDispose is intended for this.

procedure StrDispose(Str: PAnsiChar);
procedure StrDispose(Str: PWideChar);

here

  • Str is the string for which you want to free memory.

Example.

The example demonstrates how to allocate memory for a string entered from the keyboard for a console application. In this case, the length of the string at the beginning of the program is unknown and is determined during program execution.

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  ps1 : PWideChar;
  s : string;

begin
  // Function StrNew, procedure StrDispose.
  // Demonstrates memory allocation for a string,
  // entered from the keyboard. The length of the string is unknown.

  // 1. Create the original string,
  // a string is entered from the keyboard in a console application
  Write('s = ');
  Readln(s);

  // 2. Convert s => ps1
  // 2.1. Allocate memory for the string ps1 with the StrNew function,
  // the memory size is equal to the length of the string s
  ps1 := StrNew(WideStrAlloc(Length(s)));

  // 2.2. Copy string s => ps1
  StrPCopy(ps1, s);

  // 3. Display string ps1
  Writeln('ps1 = ', StrPas(ps1));

  // 4. Free memory, allocated for ps1 string
  StrDispose(ps1);

  Readln;
end.

Example.

s = BestProg
ps1 = BestProg

 

6. Functions StrPas and StrPCopy. Converting from String type to PChar type and vice versa

Useful when using strings in programs are the functions of mutual conversion between string representation formats of type String and PChar. The generic String type uses its implementations of the AnsiString and UnicodeString types, in which a character occupies 1 and 2 bytes, respectively. For the generic type PChar, there are also varieties, these are the PAnsiChar and PWideChar types that take into account different encoding systems in which characters occupy 1 and 2 bytes, respectively.

To convert from the PAnsiChar and PWideChar types to the String type, you need to use the StrPas function, which has the following declarations

function StrPas(const Str: PAnsiChar): AnsiString;
function StrPas(const Str: PWideChar): UnicodeString;

here

  • Str – the string to be converted to the AnsiString or UnicodeString type, respectively.

The StrPCopy function is used to convert from the String type to the PAnsiChar and PWideChar types. The function has the following implementations

function StrPCopy(Dest: PAnsiChar; const Source: AnsiString): PAnsiChar;
function StrPCopy(Dest: PWideChar; const Source: UnicodeString): PWideChar;

Example.

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  ps1 : PAnsiChar;
  ps2 : PWideChar;
  s : string;

begin
  // Functions StrPas and StrPCopy

  // 1. Functions StrPas
  // 1.1. Form ps1 string of PAnsiChar type
  ps1 := 'PAnsiChar';
  Writeln('ps1 = ', StrPas(ps1));

  // 1.2. Form ps2 string of PWideChar type
  ps2 := StrNew('PWideChar');
  Writeln('ps2 = ', StrPas(ps2));

  // 1.3. Convert PAnsiChar => String - function StrPas
  s := StrPas(ps1);
  Writeln('StrPas(ps1) = ', s);

  // 1.4. Convert PWideChar => String
  s := StrPas(ps2);
  Writeln('StrPas(ps2) = ', s);

  // 1.5. Free ps2
  StrDispose(ps2);

  // 2. Function StrPCopy
  // 2.1. Create string s
  s := 'String';
  Writeln('s = ', s);

  // 2.2. Allocate a fragment of 20 characters for the PAnsiChar type
  ps1 := AnsiStrAlloc(20);

  // 2.3. Copy String => PAnsiChar
  StrPCopy(ps1, s);
  Writeln('StrPCopy(s) = ', StrPas(ps1));

  // 2.4. Allocate memory for PWideChar type
  ps2 := WideStrAlloc(20);

  // 2.5. Copy String => PWideChar
  StrPCopy(ps2, s);
  Writeln('StrPCopy(s) = ', StrPas(ps2));

  // 2.6. Free memory, allocated for ps1, ps2 strings
  StrDispose(ps1);
  StrDispose(ps2);

  Readln;
end.

Result

ps1 = PAnsiChar
ps2 = PWideChar
StrPas(ps1) = PAnsiChar
StrPas(ps2) = PWideChar
s = String
StrPCopy(s) = String
StrPCopy(s) = String

 


Related topics