Страница 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'ить желательно вообще всё везде.