Problems with strings in GPC beta 971001_(re)

Tue, 28 Oct 1997 10:08:59 +0100 (MET)


Frank Heckenbach wrote:

>Strange! There has always been a check for the maximum length in the
>read[ln]
>procedure.
>
>> On the other hand, Read (F, stringVar) only reads a maximum of
>> Length(stringVar) characters [as it should].
>
>Even more strange, since Read and Readln are actually the same procedure
>(or rather function) internally. Readln (F, stringVar) first does exactly
>the
>same as Read (F, stringVar), and then a Readln (stringVar).
>
>
>Perhaps you did some other thing in your program that triggered the first
>bug?
>If not, please send me a program and sample input to show this problem.
>

MY MISTAKE!  Read[ln] work correctly and never exceeds the string capacity,
and my problems are totally UNrelated to the missing range checks in some
string expressions that I mentioned in the original post.

The strange crash in my program was indeed caused by writing to memory beyond
the string capacity (that is, overwriting something else), but I was jumping
to conclusions in blaming Readln.  The real culprit was my own buggy code
(specifically, a procedure that added a #0 to the string ...).


ADVICE TO GPC USERS:

If you add #0 to a string (in order to call functions in the C library), it
is a *very* good idea to use strings whose capacity (max length) are not
divisible by 4.  In that case, at least one byte is "wasted" to achieve
4-byte alignment, and adding #0 should not overwrite other variables. 
Alternatively, you should explicitly check that the entire capacity is not
used before adding the #0 char, like the procedure below which safely adds
#0, and returns a Cstring variable (pointer) to the string.

Regards, 

   Jesper Lund


function Get_Cstring (var s : string) : Cstring;
var
  p : Cstring;
  sLen : Integer;

begin
  sLen := Length (s);

  if (slen = s.Capacity) then    { We are about to crash .... }
  begin
    Writeln ('Fatal error in Get_Cstring: string too short');
    Halt;
  end; { if }

  p := Cstring (@s[1]);  { Generates same code as:  p := s         }
  p[sLen] := #0;         { Note: This overwrites s[sLen+1] with #0 }

  Get_Cstring := p;  { Return pointer to first element }
end; { Get_Cstring }






Jesper Lund (jel@hha.dk)

HTML conversion by Lluís de Yzaguirre i Maura
Institut de Lingüística Aplicada - Universitat "Pompeu Fabra"
e-mail: de_yza@upf.es