Сравнение PChar

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Сравнение PChar

Сообщение alexs » 22.04.2013 13:58:41

Сравнение двух PChar в случае если один из указателей = nil приводит к ошибке.
Может кто подтвердить ошибку?

Lazarus 1.1 r40873M FPC 2.7.1 [2013/02/16] i386-linux-gtk 2
Код
Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
var
  SSS1, SSS2:string;
  S1, S2:PChar;
begin
  SSS1:='Строка 1';
  SSS2:='Строка 2';
  S1:=@SSS1[1];
  S2:=@SSS2[1];
  ShowMessage('Result = ' + IntToStr(AnsiStrComp(S1, S2)));
  S1:=nil;
  S2:=@SSS2[1];
  ShowMessage('Result = ' + IntToStr(AnsiStrComp(S1, S2)));
end;

Стабильно на втором сравнение выскакивает исключение.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4064
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Сравнение PChar

Сообщение SeZuka » 22.04.2013 15:20:03

В винде работает нормально, у вас видимо линух, смотрите какую системную функцию вызывает AnsiStrComp и ее описание.
SeZuka
постоялец
 
Сообщения: 209
Зарегистрирован: 05.09.2012 14:58:05

Re: Сравнение PChar

Сообщение dunin » 22.04.2013 15:29:19

Подтверждаю. В Виндусе без ошибки (Result = -2)
Аватара пользователя
dunin
энтузиаст
 
Сообщения: 634
Зарегистрирован: 02.05.2007 13:18:11
Откуда: Тољя††и

Re: Сравнение PChar

Сообщение absdjfh » 22.04.2013 15:29:46

Lazarus 1.0.8 svn 40573 i386-win32-win32/win64 - бага нет.
Это определенно баг, так как в описании функции указано отсутствие исключений.
absdjfh
новенький
 
Сообщения: 60
Зарегистрирован: 21.01.2012 13:59:00

Re: Сравнение PChar

Сообщение alexs » 22.04.2013 15:41:24

А какой у всех FPC?
У меня 2.7.1 - есть ещё кто на таком?
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4064
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Сравнение PChar

Сообщение Widowmaker » 22.04.2013 16:21:17

Linux Mint 12 + FPC 2.4.4 - ошибка и сообщение 'Файл "../sysdeps/i386/i586/strlen.S" не найден.'
Если вместо S1:=nil; поставить пустую строку S1:='';, ошибки нет.
Аватара пользователя
Widowmaker
новенький
 
Сообщения: 37
Зарегистрирован: 27.04.2011 18:32:04

Re: Сравнение PChar

Сообщение SeZuka » 22.04.2013 16:39:24

alexs писал(а):А какой у всех FPC?

2.6.2
Проверьте что у вас вызывается в AnsiStrComp
SeZuka
постоялец
 
Сообщения: 209
Зарегистрирован: 05.09.2012 14:58:05

Re: Сравнение PChar

Сообщение kosteek » 22.04.2013 16:41:53

Подтверждаю ошибку.
Ubuntu 12.04 32bit
Lazarus 1.0.2
FPC 2.6.0
kosteek
постоялец
 
Сообщения: 203
Зарегистрирован: 24.07.2008 14:57:09
Откуда: Украина, г.Славянск

Re: Сравнение PChar

Сообщение bormant » 22.04.2013 16:44:00

FPC 2.6.0, Slackware 14.0
Код: Выделить всё
uses SysUtils;
var p1, p2: PChar;
begin
  p1 := nil; p2 := 'test';
  WriteLn(AnsiStrComp(p1, p2));
end.
Прогон:
Код: Выделить всё
-1
Аватара пользователя
bormant
постоялец
 
Сообщения: 408
Зарегистрирован: 21.03.2012 11:26:01

Re: Сравнение PChar

Сообщение debi12345 » 22.04.2013 16:53:48

winxp32 bit, fpc 2.6.0:
Код: Выделить всё
program strcomp;

{$mode objfpc}{$h+}
{$apptype console}

uses
  sysutils;

var
  sss1,sss2: ansistring;
  s1,s2: pchar;

begin
  SSS1:='Строка 1';
  SSS2:='Строка 2';
  S1:=@SSS1[1];
  S2:=@SSS2[1];
  writeln('Result = ' + IntToStr(AnsiStrComp(S1, S2)));
  S1:=nil;
  S2:=@SSS2[1];
writeln('Result = ' + IntToStr(AnsiStrComp(S1, S2)));
end.


OUTPUT:
C:\... Settings\Администратор\fpc_project\strcomp>strcomp.exe
Result = -1
Result = -2


LINUX DEBIAN6 fpc2.6.0
Result = -1
Result = -1
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Сравнение PChar

Сообщение heks » 22.04.2013 21:20:56

alexs писал(а):А какой у всех FPC?
У меня 2.7.1 - есть ещё кто на таком?


FPC 2.7.1 Lazarus 1.1 svn: 40811 win 7 максимальная sp1

Result=-1
Result=-2
heks
новенький
 
Сообщения: 29
Зарегистрирован: 23.07.2012 11:50:39

Re: Сравнение PChar

Сообщение Лекс Айрин » 22.04.2013 21:40:54

fpc 2.6.0-6
результат на проге bormantа
-1
ЗЫ: к сожалению, убунта (12.10) не дает мне использовать более новую версию. (Или руки пока кривоваты).
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Сравнение PChar

Сообщение alexs » 22.04.2013 22:47:43

Спасибо. Буду ковырять менеджер строк. Что-то тут не так.

Впопрос возник после обнаружения шибкисортировки в ZEOS. Причём ошибка провяляется и линухе и в винде. В нём дошёл до участка сравнения.
Сейчас временно в ZEOS изменил код сравнения с PChar на string.
Но это не совсем верно...
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4064
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Сравнение PChar

Сообщение debi12345 » 23.04.2013 08:53:15

AnsiStrComp вообще-то хочет НУЛЬ-заврешенные строки. Поэтому согласно доки на РТЛ было бы надежнее :
SSS1:='Строка 1'; getmem(s1,length(sss1)+1);
  SSS2:='Строка 2'; getmem(s2,length(sss2)+1);

strpcopy(s1,sss1); strpcopy(s2,sss2);
  ShowMessage('Result = ' + IntToStr(AnsiStrComp(S1, S2)));

  S1:=nil;  strpcopy(s2,sss2);
  ShowMessage('Result = ' + IntToStr(AnsiStrComp(S1, S2)));


хотя наверное в разы тормознее (из-за возни с динамической памятью).

Добавлено спустя 2 минуты 20 секунд:
А если без динамики, то делать по Вашему - но сравнивая обычной посимвольной итерацией (она может быть ускорена в разы - см. код строковых функций GLIBC ).

Добавлено спустя 9 минут 20 секунд:
Или позаботиться о НУЛЬ-терминаторе заранее:
SSS1:='Строка 1' + char(nil);
SSS2:='Строка 2' + char(nil);
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Сравнение PChar

Сообщение bormant » 23.04.2013 09:44:30

debi12345 писал(а): хочет НУЛЬ-заврешенные строки
позаботиться о НУЛЬ-терминаторе заранее
SSS1:='Строка 1' + char(nil);
Имелось в виду SSS1:='Строка 1' + #0; ?
Увольте, лишнее это всё, завершающие #0 у строковых констант обеспечиваются компилятором (пример из fpc 2.6.0):
Код: Выделить всё
var
  s1: AnsiString;
  p1: PChar;
begin
  s1 := 's1'; p1 := 'p1';
end.
Ассемблерный листинг данных:
Код: Выделить всё
.section .data
.globl   _PROGRAM$_Ld1
_PROGRAM$_Ld1:
   .ascii  "s1\000"

.section .rodata
.globl   _PROGRAM$_Ld2
_PROGRAM$_Ld2:
   .ascii  "p1\000"
\000 -- восьмеричная запись 0.
Последний раз редактировалось bormant 23.04.2013 11:02:11, всего редактировалось 2 раз(а).
Аватара пользователя
bormant
постоялец
 
Сообщения: 408
Зарегистрирован: 21.03.2012 11:26:01

След.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 6

Рейтинг@Mail.ru