Сравнение PChar

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

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

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

Сравнение PChar

Сообщение alexs »

Сравнение двух 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;

Стабильно на втором сравнение выскакивает исключение.
SeZuka
постоялец
Сообщения: 209
Зарегистрирован: 05.09.2012 14:58:05

Сообщение SeZuka »

В винде работает нормально, у вас видимо линух, смотрите какую системную функцию вызывает AnsiStrComp и ее описание.
Аватара пользователя
dunin
энтузиаст
Сообщения: 634
Зарегистрирован: 02.05.2007 13:18:11
Откуда: Тољя††и
Контактная информация:

Сообщение dunin »

Подтверждаю. В Виндусе без ошибки (Result = -2)
absdjfh
новенький
Сообщения: 60
Зарегистрирован: 21.01.2012 13:59:00

Сообщение absdjfh »

Lazarus 1.0.8 svn 40573 i386-win32-win32/win64 - бага нет.
Это определенно баг, так как в описании функции указано отсутствие исключений.
Аватара пользователя
alexs
долгожитель
Сообщения: 4066
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

А какой у всех FPC?
У меня 2.7.1 - есть ещё кто на таком?
Аватара пользователя
Widowmaker
новенький
Сообщения: 37
Зарегистрирован: 27.04.2011 18:32:04

Сообщение Widowmaker »

Linux Mint 12 + FPC 2.4.4 - ошибка и сообщение 'Файл "../sysdeps/i386/i586/strlen.S" не найден.'
Если вместо S1:=nil; поставить пустую строку S1:='';, ошибки нет.
SeZuka
постоялец
Сообщения: 209
Зарегистрирован: 05.09.2012 14:58:05

Сообщение SeZuka »

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

2.6.2
Проверьте что у вас вызывается в AnsiStrComp
kosteek
постоялец
Сообщения: 203
Зарегистрирован: 24.07.2008 14:57:09
Откуда: Украина, г.Славянск

Сообщение kosteek »

Подтверждаю ошибку.
Ubuntu 12.04 32bit
Lazarus 1.0.2
FPC 2.6.0
Аватара пользователя
bormant
постоялец
Сообщения: 408
Зарегистрирован: 21.03.2012 11:26:01

Сообщение bormant »

FPC 2.6.0, Slackware 14.0

Код: Выделить всё

uses SysUtils;
var p1, p2: PChar;
begin
  p1 := nil; p2 := 'test';
  WriteLn(AnsiStrComp(p1, p2));
end.
Прогон:
Аватара пользователя
debi12345
долгожитель
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение debi12345 »

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
heks
новенький
Сообщения: 29
Зарегистрирован: 23.07.2012 11:50:39

Сообщение heks »

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


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

Result=-1
Result=-2
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

fpc 2.6.0-6
результат на проге bormantа
-1
ЗЫ: к сожалению, убунта (12.10) не дает мне использовать более новую версию. (Или руки пока кривоваты).
Аватара пользователя
alexs
долгожитель
Сообщения: 4066
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

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

Впопрос возник после обнаружения шибкисортировки в ZEOS. Причём ошибка провяляется и линухе и в винде. В нём дошёл до участка сравнения.
Сейчас временно в ZEOS изменил код сравнения с PChar на string.
Но это не совсем верно...
Аватара пользователя
debi12345
долгожитель
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение debi12345 »

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);
Аватара пользователя
bormant
постоялец
Сообщения: 408
Зарегистрирован: 21.03.2012 11:26:01

Сообщение bormant »

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 раза.
Ответить