Страница 1 из 1
Ошибка External SIGSEGV при вызове своего класса
Добавлено:
19.04.2017 18:46:00
DropSoft
При нажатии на Button1 выдает ошибку "External SIGSEGV на строке 45: for i := 0 to 255 do buf[i] := 0;
В чем здесь ошибка? Первый раз занялся классами, чего-то не понимаю.
Помогите чайнику!
- Код: Выделить всё
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
Tbuf = array[0..255] of word;
TMyClass = class
private
{ private declarations }
public
{ public declarations }
buf : Tbuf;
procedure Clear;
end;
var
Form1: TForm1;
My1 : TMyClass;
implementation
{$R *.lfm}
procedure TMyClass.Clear;
var
i : integer;
begin
for i := 0 to 255 do buf[i] := 0;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
My1.Clear;
end;
end.
Re: Ошибка External SIGSEGV при вызове своего класса
Добавлено:
19.04.2017 18:48:45
Лекс Айрин
переменная класса не создана.
Re: Ошибка External SIGSEGV при вызове своего класса
Добавлено:
19.04.2017 18:54:52
olegy123
DropSoft писал(а):My1 : TMyClass;
тут только определили что переменная My1 имеет тип TMyClass
классы должны быть созданы My1:=TMyClass.Create();
только тогда My1 будет иметь сущность TMyClass
Re: Ошибка External SIGSEGV при вызове своего класса
Добавлено:
19.04.2017 19:29:16
DropSoft
О, спасибо!
Я правильно понимаю, что если внутри процедуры определяю переменную My1 : TMyClass;
а затем создаю My1:=TMyClass.Create();
то в конце процедуры надо поставить My1.Free
а если определена в самом модуле Unit1 как в коде выше, то My1.Free не требуется, т.к. это произойдет автоматически при закрытии программы?
Re: Ошибка External SIGSEGV при вызове своего класса
Добавлено:
19.04.2017 19:44:14
Лекс Айрин
Нет. Можно создать в одном месте, а уничтожить в другом... главное следить чтобы не использовать до и/или после существования объекта.
Re: Ошибка External SIGSEGV при вызове своего класса
Добавлено:
19.04.2017 23:10:01
java73
Рекомендую главу про ооп из книги Алексеева/Чесноковой/Кучера программирование в freepascal. Там все отлично написано по базовым навыкам.
Re: Ошибка External SIGSEGV при вызове своего класса
Добавлено:
19.04.2017 23:52:16
DropSoft
java73 Спасибо. Читаю.
Re: Ошибка External SIGSEGV при вызове своего класса
Добавлено:
20.04.2017 01:33:01
Дож
DropSoft, классы сами не уничтожаются, всегда нужно вызывать деструктор или Free (за исключением интерфейсных классов, унаследованных от TInterfacedObject).
Re: Ошибка External SIGSEGV при вызове своего класса
Добавлено:
20.04.2017 12:19:59
serbod
При работе с динамически создаваемыми объектами следует придерживаться правила,
что создание и удаление должно происходить в одном модуле, как можно ближе друг
к другу. В идеале так:
- Код: Выделить всё
Obj := TObj.Create();
try
Obj.Use();
finally
Obj.Free();
end;
Все объекты, доступные за пределами функции/процедуры/метода должны
удаляться при помощи FreeAndNil().
Re: Ошибка External SIGSEGV при вызове своего класса
Добавлено:
20.04.2017 13:04:31
DropSoft
serbod То есть, если мне надо класс использовать несколькими модулями, сам этот класс я оформил отдельным модулем MyClass, то я:
1. в остальных модулях в секции interface uses добавляю MyClass,
2. в MainForm перед implementation добавляю var My1 : TMyClass;
3. в процедуре TMainForm.FormCreate добавляю My1 := TMyClass.Create
4. работаю с классом в разных модулях
5. при закрытии программы я должен выполнить FreeAndNil(My1) где? в TMainForm.FormDestroy?
Re: Ошибка External SIGSEGV при вызове своего класса
Добавлено:
20.04.2017 13:16:06
Лекс Айрин
можно в разделе finalization
Re: Ошибка External SIGSEGV при вызове своего класса
Добавлено:
20.04.2017 13:51:19
serbod
Для объектов внутри класса рекомендуется следующая схема:
- Код: Выделить всё
type
TSomeForm = class(TForm)
private
FMy1: TMyClass; // создание и удаление доступно только внутри TSomeForm
public
property My1: TMyClass read FMy1; // наружу торчит только read-only свойство.
end;
procedure TSomeForm.FormCreate();
begin
FMy1 := TMyClass.Create();
end;
procedure TSomeForm.FormDestroy();
begin
FreeAndNil(FMy1); // если не обнулять, то сложно будет найти ошибку при обращении к "убитому" FMy1
end;
а теперь немного примеров
- Код: Выделить всё
SomeForm.My1 := nil; // не сработает, испортить не получится
// популярная проблема
My2 := SomeForm.My1;
SomeForm.Free();
if Assigned(My2) then // My2 <> nil
My2.Use(); // получаем ошибку, поскольку My2 указывает на "убитый" SomeForm.My1
Re: Ошибка External SIGSEGV при вызове своего класса
Добавлено:
21.04.2017 00:38:35
ElectroGuard
FreeAndNil'ить желательно вообще всё везде.