[fpc-pascal] ANSI String concatenation eats Linux RAM ?

Andrej Cuckov andrej at technitude.net
Sun Sep 4 15:32:54 CEST 2005


Dear all,

I have a little problem (maybe in understanding) of the usage of the
AnsiString.

I use now FPC 1.0.6 (not updated yet to 2.0.0 as have fear that
something in my old projects wont work)

I will get right on the point.
It seems to me that I can not use SA:=SA+'zzzzzzzzzzzzzzzzzzzzzzzzzz'
large number of times repeatedly without draining my linux box out of
RAM.
(SA here being ansi string)

For instance if I try to do
   var SA:AnsiString;
    SA:='';
    for i:=1 to million do begin read(ch); SA:=SA+ch; end;
my Linux box with 512MByte of RAM will start swapping so terribly that
only reset can cure it.

I do not know if this is my mis-understanding of the way the Ansi
Strings use their reference count, but I really do not know how to add a
short string to and ansi string large number of times without running
out of ram.

It seems to me that the operation SA:=SA+ch duplicates the amount of
allocated heap for the SA, and does not release the mem even after
outside of the scope (proc).

I tried also

const large=say_100_thousand_for_the_sake_of_argument;

procedure sjfaksdjfhkasdf;
var SA,SA1:AnsiString;
    s:string[255];
    i:longint;
begin
    sa:=''; sa1:=''; s:='zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz';
    for i:=1 to large do begin
        sa1:=sa + s;
        sa:=sa1; sa1:='';
        uniqueString(sa); uniqueString(sa1);
    end;
end;
begin
        sjfaksdjfhkasdf;
        //here the program uses a lot of ram as I open another console
and do ps -auxc
        readln;
end.
---

please advice if you are not so busy thank you so much

thanxa and regards
andrej


test program below, eats 38 MByte of ram. (Linux box)
-------------------------------------------
procedure test_ansi;
var s:string[255]; //not ansi
    SA:AnsiString;
    li:longint;
begin

s:='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
//say 80
    SA:='';
    for li:=1 to 1000 do begin
        SA:=SA+s;
    end;
    writeln('In proc now. length(SA)=',length(SA));
    writeln('Choose another console and do "ps -auxc", note the memory
use');
    //--- here my program has eaten 38 Mbytes, very hungry it is
    readln;

end;
begin
    writeln('In body start. Choose another console and do "ps -auxc",
note the memory use');
    //here this program uses say 2 mbyte as per normal
    readln;

    test_ansi;
    writeln('In body now. Choose another console and do "ps -auxc", note
the memory use');
    //--- here my program has eaten 38 Mbytes, very hungry it is
    readln;
    test_ansi;
    writeln('In body now. Second time Choose another console and do "ps
-auxc", note the memory
use');
    readln;
end.
---------------------------------------------------------
eoc




More information about the fpc-pascal mailing list