Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2003-07

Strange Segfault...

23 messages · 9 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

James Mills

(gdb) break 14
Breakpoint 1 at $806603c: file test4.pas, line 14. (gdb) run
Starting program: /home/pircsrv/src/test4
Enter a string:
Replace all digits with ?
Breakpoint 1, main () at test4.pas:14
14 readLn(w);
(gdb) n
X
15 replace(['0'..'9'], w, s);
(gdb) s

Program received signal SIGSEGV, Segmentation fault. $08066073 in main () at test4.pas:15
15 replace(['0'..'9'], w, s);
(gdb)

Can anyone help me find out what's going on here ? It doesn't even go into the function and just segfaults! Makes me think FPC can't handle the ['0'..'9'] passed to the function...

replace is defined as such:

procedure replace(search: String; replace: String; var s: String);
procedure replace(const chars: array of char; replace: String; var s: String);
procedure replace(search: String; replace: String; var s: String);
var
   startPos:   Integer;
   done:       Boolean;
begin
   done := FALSE;
   while NOT done do
      begin
         startPos := pos(search, s);
         if (startPos = 0) then
            begin
               done := TRUE;
            end
         else
            begin
               delete(s, startPos, length(search));
               insert(replace, s, startPos);
            end;
      end;
end;
procedure replace(const chars: array of char; replace: String; var s: String);
var
   index:      Integer;
   done:       Boolean;
begin
   done := FALSE;
   while NOT done do
      begin
         if NOT isin(s, chars, index) then
            begin
               done := TRUE;
            end
         else
            begin
               delete(s, index, 1);
               insert(replace, s, index);
            end;
      end;
end;

the isin functions are defined as such:

function isin(s: String; search: String): Boolean;
function isin(s: String; const chars: array of char): Boolean;
function isin(s: String; const chars: array of char; var index: Integer): Boolean;
function isin(s: String; search: String): Boolean;
begin
   if pos(search, s) = 0 then
      begin
         isin := FALSE;
      end
   else
      begin
         isin := TRUE;
      end
end;
function isin(s: String; const chars: array of char): Boolean;
var
   i: Integer;
begin
   isin := isin(s, chars, i);
end;
function isin(s: String; const chars: array of char; var index: Integer): Boolean;
var
   i: Integer;
begin
   isin := TRUE;
   for i := low(chars) to high(chars) do
      begin
         if NOT isin(s, '' + chars[i]) then
            begin
               index := i;
               isin := FALSE;
               break;
            end;
      end;
end;

Anything would be helpfull :)

cheers
James

- - James Mills Zero Defect Software Engineers Group - ZDSEG

Reply by email

Matt Emson
to James Mills

James, have you tried using non overloaded function calls?? ie. StrReplace and ArrReplace etc. It should take a few minutes to implement, and may yield the answer you're seeking.

I still prefer the way Delphi overloads. At least it explicitly implies it is doing so.

Matt

Reply by email

James Mills
to Matt Emson
Matt Emson wrote 6 lines
James, have you tried using non overloaded function calls?? ie. StrReplace and ArrReplace etc. It should take a few minutes to implement, and may yield the answer you're seeking. I still prefer the way Delphi overloads. At least it explicitly implies it is doing so.

No I haven't and I'm not using Delphi mode, I'm using the native FPC mode. This should make no difference however... Other overloaded functions do not have this behaviour...

cheers
James

Show quoted text 8 lines
Matt _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
- - James Mills Zero Defect Software Engineers Group - ZDSEG

Reply by email

Marco van de Voort
to James Mills: (gdb) break 14 Breakpoint 1 at $806603c: file test4.pas, line 14. (gdb) run Starting…
Show quoted text 7 lines
15 replace(['0'..'9'], w, s); (gdb) s Program received signal SIGSEGV, Segmentation fault. $08066073 in main () at test4.pas:15 15 replace(['0'..'9'], w, s); (gdb)

Passing a set ( ['0'..'9'] ) to

procedure replace(search: String; replace: String; var s: String); procedure replace(const chars: array of char; replace: String; var s: String);

A string, or a array of char?

IMHO it is logical that it crashes?

Reply by email

James Mills
to Marco van de Voort
Marco van de Voort wrote 16 lines
> 15 replace(['0'..'9'], w, s); > (gdb) s > > Program received signal SIGSEGV, Segmentation fault. > $08066073 in main () at test4.pas:15 > 15 replace(['0'..'9'], w, s); > (gdb) Passing a set ( ['0'..'9'] ) to > procedure replace(search: String; replace: String; var s: String); > procedure replace(const chars: array of char; replace: String; var s: String); A string, or a array of char? IMHO it is logical that it crashes?
I am passing ['0'..'9'] to a: const chars: array of char;

Can't you do this ? If not how else can I rewrite this function ?

cheers
James

Show quoted text 5 lines
_______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
- - James Mills Zero Defect Software Engineers Group - ZDSEG

Reply by email

Matt Emson
to Marco van de Voort: Passing a set ( ['0'..'9'] ) to A string, or a array of char? IMHO it is logical that it…
> procedure replace(search: String; replace: String; var s: String); > procedure replace(const chars: array of char; replace: String; var s:
String);
A string, or a array of char?

James, this (as Marco put it) was exactly what I had in mind. The compiler will have to make a decision, and as a string is implicitly and array of sorts, you most likely get this error.

If you had tried my advice, you would have realised this was the case quite quickly. I was going for the school of hard knocks version of the answer, rather than handing it to you on a plate :P

Matt

Reply by email

James Mills
to Matt Emson
Matt Emson wrote 13 lines
> > procedure replace(search: String; replace: String; var s: String); > > procedure replace(const chars: array of char; replace: String; var s: String); > > A string, or a array of char? James, this (as Marco put it) was exactly what I had in mind. The compiler will have to make a decision, and as a string is implicitly and array of sorts, you most likely get this error. If you had tried my advice, you would have realised this was the case quite quickly. I was going for the school of hard knocks version of the answer, rather than handing it to you on a plate :P

Well ok thanks Matt, however I kind of already had this figured out, but was posting here to find out if there's a way around it (other than naming two separate functions)...

Perhaps there isn't...

cheers
James

Show quoted text 8 lines
Matt _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
- - James Mills Zero Defect Software Engineers Group - ZDSEG

Reply by email

Matt Emson
to James Mills
Show quoted text 5 lines
Well ok thanks Matt, however I kind of already had this figured out, but was posting here to find out if there's a way around it (other than naming two separate functions)... Perhaps there isn't...

James,

only tested in Delphi, but the following would seem to work....

procedure replace(search: String; replace: String; var s: String); overload;
begin
  writeln('1');
end;
procedure replace(const chars: array of char; replace: String; var s:
String); overload;
begin
  writeln('2');
end;
procedure Test;
var
  a: array[0..9] of char;
  w, s, d: string;
begin
  replace(a, w, s); // get's '2'
  replace(d, w, s); // gets '1'
end;

Whilst this isn;t really the answer you were looking for, it works for me.

Your original version (replace(['0'..'9'], w, s);) didn't even compile in Delphi.

BTW, if you are using longstrings, you shouldn't be passing by reference, as the longstring (AnsiString) is already a pointer. If FPC handles memory in a similar way to Delphi with respects to longstrings, it may cause a performance hit if the string is fairly long (say 1024+ chars).

The other thing that worried me about your code is that the 'procedure replace(const chars: array of char; replace: String; var s: String);' uses 'index', but you don't initialize it to a sensible value, you just take for granted that it is set. I would be happier with:

function isin(s: string; const chars: array of char; var index: Integer):
Boolean;
begin
  for index := low(chars) to high(chars) do
    if not isin(s, '' + chars[index]) then begin
      Result := FALSE;
      Exit;
    end;
  Result := True;
  index := -1; //nice default to check for
end;
procedure replace(const chars: array of char; replace: string; var s:
string);
var
  index: Integer;
begin
  while true do begin
    if not isin(s, chars, index) then
      Break
    else begin
      delete(s, index, 1);
      insert(replace, s, index);
    end;
  end;
end;

Matt

Reply by email

Michael Van Canneyt
to Matt Emson
Matt Emson wrote 5 lines
BTW, if you are using longstrings, you shouldn't be passing by reference, as the longstring (AnsiString) is already a pointer. If FPC handles memory in a similar way to Delphi with respects to longstrings, it may cause a performance hit if the string is fairly long (say 1024+ chars).

Normally the performance hit is nearly zero.
No copying is done, only a reference count is increased. As it is a const, it cannot be assigned to anyway, so there will be no copy-on- write operation.

It is always a good idea to use 'Const' parameters as it will stop you from assigning values to the parameter in your procedure. Just proper coding.

Michael.

Reply by email

Matt Emson
to Michael Van Canneyt
Show quoted text 6 lines
Normally the performance hit is nearly zero. No copying is done, only a reference count is increased. As it is a const, it cannot be assigned to anyway, so there will be no copy-on- write operation. It is always a good idea to use 'Const' parameters as it will stop you

from

assigning values to the parameter in your procedure. Just proper coding.

I was revering to his use of 'var s: string' as one of the params in his functions. That is baaad. That *will* potentially make the proverbial poopy hit the fan if he changes it in any way in the routine.

Matt

Reply by email

Michael Van Canneyt
to Matt Emson
Matt Emson wrote 12 lines
> Normally the performance hit is nearly zero. > No copying is done, only a reference count is increased. As it is a > const, it cannot be assigned to anyway, so there will be no copy-on- > write operation. > > It is always a good idea to use 'Const' parameters as it will stop you from > assigning values to the parameter in your procedure. Just proper coding. I was revering to his use of 'var s: string' as one of the params in his functions. That is baaad. That *will* potentially make the proverbial poopy hit the fan if he changes it in any way in the routine.

This is correct, of course :-)

Michael.

Reply by email

Jeff Pohlmeyer

(*
How about using "set of char" instead of "array of char" ? That way, the compiler should be able to distinguish between the overloads...
*)
program repl;

type
  tSetOfChar = set of char;
procedure replace(chars: tSetOfChar; const replace: String; var s: String);
var
  i: Integer;
begin
  for i:=length(s) downto 1 do if (s[i] in chars) then begin
    delete(s, i, 1);
    insert(replace, s, i);
  end;
end;
var
  w, s:string;
begin
  s:='a1ebf2c3d45';
  readln(w);
  replace(['0'..'9'], w, s);
  writeln(s);
end.

__________________________________
Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!
http://sbc.yahoo.com

Reply by email

Matt Emson
to Jeff Pohlmeyer
Show quoted text 5 lines
(* How about using "set of char" instead of "array of char" ? That way, the compiler should be able to distinguish between the overloads... *)

Yeah, that will work ;-) The only problem would be if he wanted to remove specific patterns of chars, but I'm guessing this isn't the case.

Matt

Reply by email

James Mills
to Jeff Pohlmeyer: (* How about using "set of char" instead of "array of char" ? That way, the compiler…
Jeff Pohlmeyer wrote 28 lines
(* How about using "set of char" instead of "array of char" ? That way, the compiler should be able to distinguish between the overloads... *) program repl; type tSetOfChar = set of char; procedure replace(chars: tSetOfChar; const replace: String; var s: String); var i: Integer; begin for i:=length(s) downto 1 do if (s[i] in chars) then begin delete(s, i, 1); insert(replace, s, i); end; end; var w, s:string; begin s:='a1ebf2c3d45'; readln(w); replace(['0'..'9'], w, s); writeln(s); end.

Thank you, this worked quite well and is what I needed. And yes Matt Emson, I do understand why my original functions weren't working :)

cheers
James

Show quoted text 10 lines
__________________________________ Do you Yahoo!? SBC Yahoo! DSL - Now only $29.95 per month! http://sbc.yahoo.com _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
- - James Mills Zero Defect Software Engineers Group - ZDSEG

Reply by email

James Mills
to Matt and Lisa Emson
Matt and Lisa Emson wrote
> And yes Matt > Emson, I do understand why my original functions weren't working :) including the part about not passing Strings as var params too? ;-P

Yes and no. Why is it so bad to write a function in that way ? It could of course be written two different ways, but I'd rather this way where I modify the string passed to the function.

Explain it to me :) (I'm the only one that works on this project of ~30,000 LOC, so I don't see any problem)

cheers
James

Show quoted text 5 lines
_______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
- - James Mills Zero Defect Software Engineers Group - ZDSEG

Reply by email

Matt Emson
to James Mills
Show quoted text 6 lines
Yes and no. Why is it so bad to write a function in that way ? It could of course be written two different ways, but I'd rather this way where I modify the string passed to the function. Explain it to me :) (I'm the only one that works on this project of ~30,000 LOC, so I don't see any problem)

Turbo Pascal and Delphi 1 had a type called 'String'. This was limited to 255 chars, size of 256 chars, and position 0 holds the strings length. Delphi 2+ has a type called shortstring that behaves in exactly the same way as the old style string.

Delphi 2+ altered the string type to be a pointer to a chunk of memory, and added a whole load of compiler magic to make strings automatically grow and shrink, added reference counting and 'copy of change' functionality (the last two to aid in not having to copy a string until someone alters it.) This is where your problem lies.

Because FPC mimics Delphi string functionality, basically you'll end up with similar results.

You'd be much better off Returning a value, and thereby avoiding the potential for big allocation/deallocations. That or use shortstrings.

Matt

Reply by email

Alan Mead
to Matt Emson

I'm running into this string problem as well. I'd like to use strings longer than 255 but I get strange errors like:

seq-bayes]$ fpc mcmc3pl.pas
Free Pascal Compiler version 1.0.6 [2002/05/23] for i386 Copyright (c) 1993-2002 by Florian Klaempfl
Target OS: Linux for i386
Compiling mcmc3pl.pas
Assembling mcmc3pl
Linking mcmc3pl
mcmc3pl.o: In function `_READ_CONFIG$INTEGER$INTEGER$STRING$STRING': mcmc3pl.o(.text+0x147): undefined reference to
`FPC_READ_TEXT_LONGSTR'
mcmc3pl.o(.text+0x17c): undefined reference to `FPC_VAL_SINT_LONGSTR' mcmc3pl.o(.text+0x243): undefined reference to
`FPC_READ_TEXT_LONGSTR'
mcmc3pl.o(.text+0x278): undefined reference to `FPC_VAL_SINT_LONGSTR' mcmc3pl.pas(215) Error: Error while linking
Closing script ppas.sh

seq-bayes]$ fpc test_string500
Free Pascal Compiler version 1.0.6 [2002/05/23] for i386 Copyright (c) 1993-2002 by Florian Klaempfl
Target OS: Linux for i386
Compiling test_string500.pas
test_string500.pas(15,13) Fatal: Internal error 8888

These errors disappear when I edit the string definitions back to length 255 or less. Should I just avoid using longer strings or is there a compiler switch I have to include? Or is there a tutorial on FPC strings (I never used Delphi much)? Or is this behavior fixed in 1.0.10?

-Alan

--- Matt Emson wrote 44 lines
> Yes and no. Why is it so bad to write a function in that way ? It could > of course be written two different ways, but I'd rather this way where I > modify the string passed to the function. > > Explain it to me :) (I'm the only one that works on this project of > ~30,000 LOC, so I don't see any problem) Turbo Pascal and Delphi 1 had a type called 'String'. This was limited to 255 chars, size of 256 chars, and position 0 holds the strings length. Delphi 2+ has a type called shortstring that behaves in exactly the same way as the old style string. Delphi 2+ altered the string type to be a pointer to a chunk of memory, and added a whole load of compiler magic to make strings automatically grow and shrink, added reference counting and 'copy of change' functionality (the last two to aid in not having to copy a string until someone alters it.) This is where your problem lies. Because FPC mimics Delphi string functionality, basically you'll end up with similar results. You'd be much better off Returning a value, and thereby avoiding the potential for big allocation/deallocations. That or use shortstrings. Matt _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

__________________________________
Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!
http://sbc.yahoo.com

Reply by email

James Mills
to Alan Mead
Alan Mead wrote 32 lines
I'm running into this string problem as well. I'd like to use strings longer than 255 but I get strange errors like: seq-bayes]$ fpc mcmc3pl.pas Free Pascal Compiler version 1.0.6 [2002/05/23] for i386 Copyright (c) 1993-2002 by Florian Klaempfl Target OS: Linux for i386 Compiling mcmc3pl.pas Assembling mcmc3pl Linking mcmc3pl mcmc3pl.o: In function `_READ_CONFIG$INTEGER$INTEGER$STRING$STRING': mcmc3pl.o(.text+0x147): undefined reference to `FPC_READ_TEXT_LONGSTR' mcmc3pl.o(.text+0x17c): undefined reference to `FPC_VAL_SINT_LONGSTR' mcmc3pl.o(.text+0x243): undefined reference to `FPC_READ_TEXT_LONGSTR' mcmc3pl.o(.text+0x278): undefined reference to `FPC_VAL_SINT_LONGSTR' mcmc3pl.pas(215) Error: Error while linking Closing script ppas.sh seq-bayes]$ fpc test_string500 Free Pascal Compiler version 1.0.6 [2002/05/23] for i386 Copyright (c) 1993-2002 by Florian Klaempfl Target OS: Linux for i386 Compiling test_string500.pas test_string500.pas(15,13) Fatal: Internal error 8888 These errors disappear when I edit the string definitions back to length 255 or less. Should I just avoid using longer strings or is there a compiler switch I have to include? Or is there a tutorial on FPC strings (I never used Delphi much)? Or is this behavior fixed in 1.0.10?

I believe there is a compiler switch.

cheers
James

Show quoted text 57 lines
-Alan --- Matt Emson wrote: > > Yes and no. Why is it so bad to write a function in that way ? It > could > > of course be written two different ways, but I'd rather this way > where I > > modify the string passed to the function. > > > > Explain it to me :) (I'm the only one that works on this project > of > > ~30,000 LOC, so I don't see any problem) > > Turbo Pascal and Delphi 1 had a type called 'String'. This was > limited to > 255 chars, size of 256 chars, and position 0 holds the strings > length. > Delphi 2+ has a type called shortstring that behaves in exactly the > same way > as the old style string. > > Delphi 2+ altered the string type to be a pointer to a chunk of > memory, and > added a whole load of compiler magic to make strings automatically > grow and > shrink, added reference counting and 'copy of change' functionality > (the > last two to aid in not having to copy a string until someone alters > it.) > This is where your problem lies. > > Because FPC mimics Delphi string functionality, basically you'll > end up with > similar results. > > You'd be much better off Returning a value, and thereby avoiding > the > potential for big allocation/deallocations. That or use > shortstrings. > > Matt > > > > _______________________________________________ > fpc-pascal maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-pascal __________________________________ Do you Yahoo!? SBC Yahoo! DSL - Now only $29.95 per month! http://sbc.yahoo.com _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
- - James Mills Zero Defect Software Engineers Group - ZDSEG

Reply by email

Alan Mead
to James Mills
--- James Mills wrote
On Mon, Jul 14, 2003 at 06:48:06AM -0700, Alan Mead wrote: > I'm running into this string problem as well. I'd like to use > strings longer than 255 but I get strange errors like: >

[...]

I believe there is a compiler switch.

If there is, I cannot find it. {$H} does nothing and I re-read the portion of the docs that deal with the sting types again and I don't see what I'm doing wrong.

If I declare "stmp: ansiString;" then the executable compiles and links fine but the strings don't actually work. For example, I "readln(txt,stmp);" and stmp only receives the first 255 columns of the file.

-Alan

__________________________________
Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!
http://sbc.yahoo.com

Reply by email

Jonas Maebe
to Alan Mead
Alan Mead wrote
If there is, I cannot find it. {$H} does nothing and I re-read the portion of the docs that deal with the sting types again and I don't see what I'm doing wrong.

There is a difference between longstrings and ansistrings. Ansistrings are fully supported, but longstrings (which is what you are using) aren't. To use ansistrings, either use {$h+} and declare your variable as "string" (i.e., without [lenght]), or use "ansistring" as type.

Jonas

Reply by email

Unknown author
to Alan Mead: [...] If there is, I cannot find it. {$H} does nothing and I re-read the portion of the…
Alan Mead wrote 14 lines
--- James Mills wrote: > On Mon, Jul 14, 2003 at 06:48:06AM -0700, Alan Mead wrote: > > I'm running into this string problem as well. I'd like to use > > strings longer than 255 but I get strange errors like: > > [...] > I believe there is a compiler switch. If there is, I cannot find it. {$H} does nothing and I re-read the portion of the docs that deal with the sting types again and I don't see what I'm doing wrong.
{$H+}
or
{$H-}

definitely works.

Show quoted text 5 lines
If I declare "stmp: ansiString;" then the executable compiles and links fine but the strings don't actually work. For example, I "readln(txt,stmp);" and stmp only receives the first 255 columns of the file.

what version are you using ?

Michael.

Reply by email

Alan Mead
to Unknown author
--- wrote 6 lines
{$H+} or {$H-} definitely works.

Sorry, by does nothing I meant that it does nothing to solve my problems with strings. Of course, the fundamental problem is that I don't fully understand anything but old-fashioned TP strings.

seq-bayes]$ fpc test_string500
Free Pascal Compiler version 1.0.6 [2002/05/23] for i386 Copyright (c) 1993-2002 by Florian Klaempfl
Target OS: Linux for i386
Compiling test_string500.pas
test_string500.pas(21,13) Fatal: Internal error 8888

I'll upgrade to 1.0.10 soon ... so if that solves this problem, great.

-Alan

__________________________________
Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!
http://sbc.yahoo.com

Reply by email