Ошибка External SIGSEGV при вызове своего класса

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

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

Ошибка External SIGSEGV при вызове своего класса

Сообщение DropSoft » 19.04.2017 18:46:00

При нажатии на 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.   
DropSoft
новенький
 
Сообщения: 31
Зарегистрирован: 31.03.2013 13:47:40

Re: Ошибка External SIGSEGV при вызове своего класса

Сообщение Лекс Айрин » 19.04.2017 18:48:45

переменная класса не создана.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Ошибка External SIGSEGV при вызове своего класса

Сообщение olegy123 » 19.04.2017 18:54:52

DropSoft писал(а):My1 : TMyClass;

тут только определили что переменная My1 имеет тип TMyClass
классы должны быть созданы My1:=TMyClass.Create();
только тогда My1 будет иметь сущность TMyClass
olegy123
долгожитель
 
Сообщения: 1643
Зарегистрирован: 25.02.2016 12:10:20

Re: Ошибка External SIGSEGV при вызове своего класса

Сообщение DropSoft » 19.04.2017 19:29:16

О, спасибо!

Я правильно понимаю, что если внутри процедуры определяю переменную My1 : TMyClass;
а затем создаю My1:=TMyClass.Create();
то в конце процедуры надо поставить My1.Free

а если определена в самом модуле Unit1 как в коде выше, то My1.Free не требуется, т.к. это произойдет автоматически при закрытии программы?
DropSoft
новенький
 
Сообщения: 31
Зарегистрирован: 31.03.2013 13:47:40

Re: Ошибка External SIGSEGV при вызове своего класса

Сообщение Лекс Айрин » 19.04.2017 19:44:14

Нет. Можно создать в одном месте, а уничтожить в другом... главное следить чтобы не использовать до и/или после существования объекта.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Ошибка External SIGSEGV при вызове своего класса

Сообщение java73 » 19.04.2017 23:10:01

Рекомендую главу про ооп из книги Алексеева/Чесноковой/Кучера программирование в freepascal. Там все отлично написано по базовым навыкам.
java73
постоялец
 
Сообщения: 257
Зарегистрирован: 21.11.2013 09:08:10

Re: Ошибка External SIGSEGV при вызове своего класса

Сообщение DropSoft » 19.04.2017 23:52:16

java73 Спасибо. Читаю.
DropSoft
новенький
 
Сообщения: 31
Зарегистрирован: 31.03.2013 13:47:40

Re: Ошибка External SIGSEGV при вызове своего класса

Сообщение Дож » 20.04.2017 01:33:01

DropSoft, классы сами не уничтожаются, всегда нужно вызывать деструктор или Free (за исключением интерфейсных классов, унаследованных от TInterfacedObject).
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Ошибка External SIGSEGV при вызове своего класса

Сообщение serbod » 20.04.2017 12:19:59

При работе с динамически создаваемыми объектами следует придерживаться правила,
что создание и удаление должно происходить в одном модуле, как можно ближе друг
к другу. В идеале так:
Код: Выделить всё
Obj := TObj.Create();
try
  Obj.Use();
finally
  Obj.Free();
end;


Все объекты, доступные за пределами функции/процедуры/метода должны
удаляться при помощи FreeAndNil().
Аватара пользователя
serbod
постоялец
 
Сообщения: 449
Зарегистрирован: 16.09.2016 11:03:02
Откуда: Минск

Re: Ошибка External SIGSEGV при вызове своего класса

Сообщение DropSoft » 20.04.2017 13:04:31

serbod То есть, если мне надо класс использовать несколькими модулями, сам этот класс я оформил отдельным модулем MyClass, то я:
1. в остальных модулях в секции interface uses добавляю MyClass,
2. в MainForm перед implementation добавляю var My1 : TMyClass;
3. в процедуре TMainForm.FormCreate добавляю My1 := TMyClass.Create
4. работаю с классом в разных модулях
5. при закрытии программы я должен выполнить FreeAndNil(My1) где? в TMainForm.FormDestroy?
DropSoft
новенький
 
Сообщения: 31
Зарегистрирован: 31.03.2013 13:47:40

Re: Ошибка External SIGSEGV при вызове своего класса

Сообщение Лекс Айрин » 20.04.2017 13:16:06

можно в разделе finalization
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Ошибка External SIGSEGV при вызове своего класса

Сообщение serbod » 20.04.2017 13:51:19

Для объектов внутри класса рекомендуется следующая схема:

Код: Выделить всё
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
Аватара пользователя
serbod
постоялец
 
Сообщения: 449
Зарегистрирован: 16.09.2016 11:03:02
Откуда: Минск

Re: Ошибка External SIGSEGV при вызове своего класса

Сообщение ElectroGuard » 21.04.2017 00:38:35

FreeAndNil'ить желательно вообще всё везде.
ElectroGuard
новенький
 
Сообщения: 71
Зарегистрирован: 03.06.2016 12:10:22


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

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

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

Рейтинг@Mail.ru