Освобождение памяти экземпляра класса

Вопросы программирования и использования среды Lazarus.

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

Освобождение памяти экземпляра класса

Сообщение BamsikPotapov » 22.04.2020 00:35:38

Добрый вечер!
Судьба заставила вспомнить программирование(хотя я его особо и не знаю).
В конце программы я пытаюсь освободить память выделенную под массив элементов типа класс который написал сам.
В коде все видно что и как я делаю. Я решил немного поиграться с классом перед написанием кода и сразу получил проблему по нажатии кнопки меню выход пишу Item[i].Free; и все падает. Промежуточный код может показаться непонятным я просто вспоминаю как работать с файлом. Главный вопрос про высвобождение памяти.
Поясните что не так. У меня в распоряжении пару учебников с интернета и в них пишут как сделать вроде повторяю и ловлю ошибку. Я обновил Лазарус до новой версии(старая была 6 летней давности).

Вот код:

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

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Menus, ComCtrls,
  Buttons, PairSplitter, EditBtn, ExtCtrls, StdCtrls;

type
  TItems = class
    art: Word;
    Name: String[128];
  end;

  { TForm1 }

  TForm1 = class(TForm)
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
    BitBtn3: TBitBtn;
    BitBtn4: TBitBtn;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    GroupBox1: TGroupBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    ListBox1: TListBox;
    MainMenu1: TMainMenu;
    MenuItem1: TMenuItem;
    MenuItem2: TMenuItem;
    PairSplitter1: TPairSplitter;
    PairSplitterSide1: TPairSplitterSide;
    PairSplitterSide2: TPairSplitterSide;
    StatusBar1: TStatusBar;
    procedure BitBtn4Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure MenuItem2Click(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;
  Item: array [1..256] of TItems;
  i: word;
  information: file of TItems;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.MenuItem2Click(Sender: TObject);
begin
  For i:=1 to 256 do Item[i].Free;
  Close;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  For i:=1 to 256 do
  Begin
    Item[i]:=TItems.Create;
    Item[i].art:=0;
  end;
  Item[1].art:=1;
  Item[1].Name:='Колесо';
  Item[2].art:=2;
  Item[2].Name:='Колесо с тормозом';
  Item[3].art:=3;
  Item[3].Name:='Тест';
  AssignFile(Information,'Information.dat');
  if FileExists('Information.dat')=true then Reset(Information) else Rewrite(Information);
  Write(Information,Item[1],Item[2],Item[3]);
  CloseFile(Information);
end;

procedure TForm1.BitBtn4Click(Sender: TObject);
begin
  If Edit4.Caption='1' then
    Begin
    Reset(Information);
    Read(Information,Item[4]);
    CloseFile(Information);
    Edit1.Caption:=IntToStr(Item[4].art);
    Edit2.Caption:=Item[4].Name;
    end;
  If Edit4.Caption='22' then
    Begin
    Reset(Information);
    Read(Information,Item[4],Item[5],Item[6]);
    CloseFile(Information);
    Edit1.Caption:=IntToStr(Item[6].art);
    Edit2.Caption:=Item[6].Name;
    end;
end;


end.
Аватара пользователя
BamsikPotapov
новенький
 
Сообщения: 53
Зарегистрирован: 31.12.2011 19:30:39
Откуда: Меня в капусте нашли

Re: Освобождение памяти экземпляра класса

Сообщение Снег Север » 22.04.2020 07:03:23

Поясните, что значит "падает" - какая ошибка при этом выдается? У меня ваш код в части создания и освобождения элементов массива выполнился без ошибок.
ЗЫ. Если вам надо только хранить пару полей, то вам не нужен класс, достаточно record. Сейчас его возможности расширены, там могут быть и процедуры. А все проблемы с созданием/удалением отпадают и память освободится автоматически.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2995
Зарегистрирован: 27.11.2007 16:14:47

Re: Освобождение памяти экземпляра класса

Сообщение BamsikPotapov » 22.04.2020 14:39:49

Я вчера уже переписал код с использованием record. Ошибка возникала SIGSEGV 10000000 что-то вроде этого. Я использовал класс только для спортивного интереса. Никогда не делал хотел посмотреть как справлюсь. Но потом вспомнил про record и все само собой получилось.
У меня вопрос на будущее очищать память под объект элемент класса можно в любом месте программы(событие любое хоть нажатие клавиши мыши? при работе с файлами ограничения имеются?).
И вопрос не по теме когда-то версия Lazarus была 1.х.х и на сайте было что-то вроде рекламы что разработчики выпустили книгу. Она есть в переводе на русский?
Аватара пользователя
BamsikPotapov
новенький
 
Сообщения: 53
Зарегистрирован: 31.12.2011 19:30:39
Откуда: Меня в капусте нашли

Re: Освобождение памяти экземпляра класса

Сообщение Снег Север » 22.04.2020 16:15:42

Есть книжка
http://popovevgeniy.000webhostapp.com/d ... azarus.zip

Уничтожать экземпляры вручную созданного класса вы можете в любом месте, где после этого, гарантированно, не может быть попытка вызова удаленного экземпляра. Обычно это делают перед закрытием формы/программы. Есть компоненты ObjectList, TClassList специально для хранения набора экземпляров и у них есть параметр отвечающий за автоматическую очистку содержимого при удалении самого компонента.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2995
Зарегистрирован: 27.11.2007 16:14:47


Вернуться в Lazarus

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

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

Рейтинг@Mail.ru