Ошибки при использовании обьектов

Форум для изучающих FPC и их учителей.

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

Ошибки при использовании обьектов

Сообщение AlexP » 06.02.2013 03:10:33

1. Наткнулся на такую ошибку при пошаговой отладке, если один обьект наследник другого. Вот пример -

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

end;

tchild=object(tparent)
i:integer;
constructor init;
end;

var Form1: TForm1;

implementation  { TForm1 }    {$R *.lfm}

procedure TForm1.Button1Click(Sender: TObject);
var x:tchild;
begin
x.init;
showmessage(inttostr(x.i));
end;

constructor tchild.init;
begin
i:=10;
end;


По идее, тут никакой ошибки нет, программа компилируется, выполняется и показывает сообщение showmessage.
Но при отладке, если точка останова находится на строке x.init или showmessage(inttostr(x.i)); то при останове возникает такая ошибка -

"gdb.exe - ошибка приложения. Инструкция по адресу 0x77c37740 обратилась к памяти по адресу "0x0000000000". Память не может быть read."

Подробности в следующем окне "ошибка отладчика" показывают -

"Команда GDB:
"-stack-list-locals 1"
не возвратила никакого результата.

Процесс GDB больше не выполняется."

2. Если есть перегруженный оператор присваивания для обьекта (результат - целое число), то будет возникать ошибка, если этот результат непосредственно подставить в индекс массива, например -

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

end;

var Form1: TForm1;

operator :=(cc:tobj)r:integer;

implementation  { TForm1 }    {$R *.lfm}

operator :=(cc:tobj)r:integer;
begin
r:=0;
end;

procedure TForm1.Button2Click(Sender: TObject);
var x:array of integer;
  cc:tobj;
begin
showmessage(inttostr(cc)); //ОК, появляется сообщение и показывает ноль
setlength(x,1);
x[cc]:=10; //ошибка - "Проект вызвал класс иключения 'External: SIGSEGV'"
end;


ошибка "Проект вызвал класс исключения 'External: SIGSEGV'" в строке x[cc]:=10; возникает при пошаговом выполнении, при работе программы ошибка "Access violation"

Это глюки у Лазаруса или я что-то делаю не так?

Лазарус 1.0.4, winXP. Пробовал на двух компах, в том числе и свежеустановленный.
AlexP
новенький
 
Сообщения: 20
Зарегистрирован: 11.05.2007 19:04:01

Re: Ошибки при использовании обьектов

Сообщение Максим » 06.02.2013 03:22:05

Lazarus к обеим этим проблемам отношения не имеет. Это компилятор и/или отладчик.

Проверяйте с FPC версии 2.7.1 и, если воспроизведётся, пишите в багтрекер FPC.
Аватара пользователя
Максим
энтузиаст
 
Сообщения: 598
Зарегистрирован: 27.07.2007 01:51:43
Откуда: Москва

Re: Ошибки при использовании обьектов

Сообщение xdsl » 06.02.2013 10:24:34

По второму примеру.
Проблема, похоже не в объектах, а в использовании неинициализированных статических структур нулевой длины (sizeof возвращает 0).
Поставьте record вместо object - получите такую-же ошибку. Но достаточно завести хотя-бы одно поле в структуре, или инициализировать ее выносом в глобальную область видимости - ошибка исчезает.
xdsl
постоялец
 
Сообщения: 131
Зарегистрирован: 15.01.2009 13:49:03

Re: Ошибки при использовании обьектов

Сообщение AlexP » 07.02.2013 00:02:06

Максим писал(а):Lazarus к обеим этим проблемам отношения не имеет. Это компилятор и/или отладчик.

Проверяйте с FPC версии 2.7.1 и, если воспроизведётся, пишите в багтрекер FPC.


Спасибо. Попробую сделать всё это. Хотя если бы более опытный человек это сделал, то было бы намного быстрее, т.к. никогда ни с тем, ни с другим дела не имел пока.

xdsl писал(а):По второму примеру.
Проблема, похоже не в объектах, а в использовании неинициализированных статических структур нулевой длины (sizeof возвращает 0).
Поставьте record вместо object - получите такую-же ошибку. Но достаточно завести хотя-бы одно поле в структуре, или инициализировать ее выносом в глобальную область видимости - ошибка исчезает.


>Поставьте record вместо object - получите такую-же ошибку.
Да.

>Но достаточно завести хотя-бы одно поле в структуре,
Нет, остаётся, независимо от того, это object или record

> или инициализировать ее выносом в глобальную область видимости
Когда вынес то да, исчезла, даже если не заводить поле в структуре.

Дальше ради интереса решил ещё посмотреть и получил вот что -

1. Если в этом случае к обьекту добавить конструктор, то ошибка возникает.

Код: Выделить всё
tobj=object
constructor init;
end;

var Form1: TForm1;
cc:tobj;

operator :=(cc:tobj)r:integer;

implementation  { TForm1 }    {$R *.lfm}

constructor tobj.init;
begin

end;

operator :=(cc:tobj)r:integer;
begin
r:=0;
end;

procedure TForm1.Button2Click(Sender: TObject);
var x:array of integer;
begin
cc.init;
showmessage(inttostr(cc)); //ОК, показывает ноль
setlength(x,1);
x[cc]:=10; //ошибка - "Проект вызвал класс иключения 'External: SIGSEGV'"
end;


2. Если в этом случае добавить поле к обьекту, то ошибка пропадает.

Код: Выделить всё
tobj=object
  i:integer;
constructor init;
end;

var Form1: TForm1;
cc:tobj;

operator :=(cc:tobj)r:integer;

implementation  { TForm1 }    {$R *.lfm}

constructor tobj.init;
begin
i:=10;
end;

operator :=(cc:tobj)r:integer;
begin
r:=0;
end;

procedure TForm1.Button2Click(Sender: TObject);
var x:array of integer;
begin
cc.init;
showmessage(inttostr(cc)); //ОК, показывает ноль
setlength(x,1);
x[cc]:=10; //ошибка - "Проект вызвал класс иключения 'External: SIGSEGV'"
end;


3. Если этот обьект сделать наследником другого, пустого обьекта с конструктором, то ошибка опять появляется.

Код: Выделить всё
tobj0=object
constructor init;
end;

tobj=object(tobj0)
  i:integer;
constructor init;
end;

var Form1: TForm1;
cc:tobj;

operator :=(cc:tobj)r:integer;

implementation  { TForm1 }    {$R *.lfm}

constructor tobj0.init;
begin

end;

constructor tobj.init;
begin
i:=10;
end;

operator :=(cc:tobj)r:integer;
begin
r:=0;
end;

procedure TForm1.Button2Click(Sender: TObject);
var x:array of integer;
begin
cc.init;
showmessage(inttostr(cc)); //ОК, показывает ноль
setlength(x,1);
x[cc]:=10; //ошибка - "Проект вызвал класс иключения 'External: SIGSEGV'"
end;


4. Если тогда обьекту родителю сделать какое-нибудь поле, то ошибка опять пропадает.
AlexP
новенький
 
Сообщения: 20
Зарегистрирован: 11.05.2007 19:04:01

Re: Ошибки при использовании обьектов

Сообщение Максим » 07.02.2013 00:26:00

AlexP писал(а):Спасибо. Попробую сделать всё это. Хотя если бы более опытный человек это сделал, то было бы намного быстрее, т.к. никогда ни с тем, ни с другим дела не имел пока.

Дерзайте. Учиться никогда не поздно.
Аватара пользователя
Максим
энтузиаст
 
Сообщения: 598
Зарегистрирован: 27.07.2007 01:51:43
Откуда: Москва

Re: Ошибки при использовании обьектов

Сообщение xdsl » 07.02.2013 07:33:49

AlexP писал(а):>Но достаточно завести хотя-бы одно поле в структуре,
Нет, остаётся, независимо от того, это object или record

Примеры прикреплены, можете проверить. Ошибку генерирует только комбинация "пустой локальный объект". Linux, fpc 2.6

P.S. Нет, на мой взгляд, смысла исследовать устаревшую object-модель, поддерживаемую только ради совместимости со старинным турбо-паскалем. Вряд-ли кто-то возмется исправлять в ней баги. Вот если-бы проблема была на уровне классов, тогда другое дело.
Однако найденный Вами баг касается и записей, а это уже серьезно, с этим стоит разбираться.
Вложения
progs.7z
(510 байт) Скачиваний: 456
xdsl
постоялец
 
Сообщения: 131
Зарегистрирован: 15.01.2009 13:49:03


Вернуться в Обучение Free Pascal

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

Рейтинг@Mail.ru