Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.02.17;
Скачать: [xml.tar.bz2];

Вниз

что-то с выделением памяти   Найти похожие ветки 

 
ghg   (2003-02-06 09:50) [0]

Дело в следующем, создаю класс (код ниже).
Потом при изменении его параметров уничтожаю его и создаю заново, но блин вылетает AccessViolation.

В связи с этим вопрос, правильно ли я описал конструкторы и деструкторы класса?

Прошу прощения за большое количество кода.


unit Unit1;
interface

uses
Windows, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, FileCtrl, math;

type
Sreda = array [1..50] of single;

type
TData_Piket = class
public
size_piket : integer;
File_name_piket, date_piket : shortstring;
x_piket, y_piket, z_piket : single;
constructor Create;
end;

Parray_piket = ^TData_Piket;

TData_Ked = class
public
kol_luch_ked, number_ked : integer;
angle_ked, radius_ked : array [1..8] of single;
piket_ked : array [1..10000] of parray_piket;
constructor Create(nked : integer);
destructor Destroy; override;
end;

TData_square = class
public
Nt_square : integer;
map_square : Tbitmap;
kol_3d_color_square : integer;
rho_3d_square : array of single;
color_3d_square : array of Tcolor;
ked_square : array [1..kol_ked] of Tdata_ked;
constructor Create;
destructor Destroy; override;
end;

TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
OpenDialog1: TOpenDialog;
SaveDialog1: TSaveDialog;
Button3: TButton;
DirectoryListBox1: TDirectoryListBox;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
square : Tdata_square;
ooo : file;
kol_3d_s, ked_s : integer;
piket_k : array [1..kol_ked] of integer;

implementation

{$R *.DFM}

constructor Tdata_piket.Create;
var i : integer;
begin
size_piket:=2*200+75;
date_piket:="10.10.10";
File_name_piket:="00";
x_piket:=0; y_piket:=0; z_piket:=0;
end;

constructor Tdata_ked.Create(nked : integer);
var i : integer;
begin
for i:=1 to piket_k[nked] do
begin
new(piket_ked[i]);
piket_ked[i]^:=Tdata_piket.Create;
end;
kol_luch_ked:=8; number_ked:=nked;
for i:= 1 to 8 do
begin
angle_ked[i]:=45*i; radius_ked[i]:=500;
end;
end;

destructor Tdata_ked.Destroy;
var i: integer;
begin
inherited;
for i:=1 to piket_k[self.number_ked] do
begin
piket_ked[i]^.Free;
piket_ked[i]^:=nil;
end;
end;

constructor Tdata_square.Create;
var i : integer;
begin
for i:=1 to kol_ked{ked_s} do ked_square[i]:=TData_Ked.create(i);
setlength(rho_3d_square,kol_3d_s+1);
setlength(color_3d_square,kol_3d_s+1);
for i:=1 to kol_3d_s do
begin
color_3d_square[i]:=$00000000+i*$0000001a;
rho_3d_square[i]:=i*10;
end;
kol_3d_color_square:=kol_3d_s;
for i:=1 to 3 do
begin
Rho_square[i]:=i*10; H_square[i]:=i*10;
end;
map_square:=nil;
Nt_square:=length(ked_square[1].piket_ked[1]^.Tms_piket);
end;

destructor Tdata_square.Destroy;
var i : integer;
begin
inherited;
map_square:=nil;
for i:=1 to kol_ked do ked_square[i].free;
setlength(rho_3d_square,0); setlength(color_3d_square,0);
end;


procedure TForm1.FormCreate(Sender: TObject);
var i : integer;
begin
ked_S:=0;
for i:=1 to kol_ked do piket_k[i]:=0;
piket_k[1]:=1; kol_3d_s:=10;
square:=TData_square.create;
end;

end.



Заранее благодарен.


 
icWasya   (2003-02-06 10:42) [1]

убери вот это
Parray_piket = ^TData_Piket;

и соответственно замени строки
piket_ked : array [1..10000] of TData_Piket;

piket_ked[i]:=Tdata_piket.Create;

begin
piket_ked[i].Free;
piket_ked[i]:=nil;
end;


 
ghg   (2003-02-06 11:02) [2]

Дык память жалко, я ведь не все поля здесь показал.

В том то и суть чтобы сделать динамическое выделение памяти.


 
icWasya   (2003-02-06 11:06) [3]

динамическое выделение подо что ??

если под TData_Piket то и так выделение происходит динамически


 
ghg   (2003-02-06 11:11) [4]

количество TData_Piket я узнаю уже во время выполнения, соответственно память хочется выделять столько сколько надо и не больше.
А при статическом массиве TData_Piket память выделяется сразу на весь массив, хотя мне может понадобиться не 10000, а всего 100.

Так вот вопрос то, правильно ли написаны конструкторы и деструкторы?


 
icWasya   (2003-02-06 11:23) [5]

ты пишешь

destructor Tdata_ked.Destroy;
var i: integer;
begin
inherited;
for i:=1 to piket_k[self.number_ked] do
begin
piket_ked[i]^.Free;
piket_ked[i]^:=nil;
end;
end;


если не хочешь прислушаться к первому замечанию то деструктор перепиши так

destructor Tdata_ked.Destroy;
var i: integer;
begin
for i:=1 to piket_k[self.number_ked] do
begin
piket_ked[i]^.Free;
piket_ked[i]^:=nil;
delete(piket_ked[i]); // !!!
piket_ked[i]:=nil; // !!!

end;

inherited; // !!!!!!!

end;



а всё-таки зачем нужно

Parray_piket = ^TData_Piket;
????????



 
DarkGreen   (2003-02-06 11:35) [6]

1. inherited конструторы западло видать вызывать.
2. В деструктора inherited деструкторы завутся в последнюю очередь


 
ghg   (2003-02-06 11:38) [7]

piket_ked : array [1..10000] of parray_piket;
это массив указателей, который имеет размер 4б*(кол-во объявленных parray_piket-ов), прибавим память выделяемую на сами Tdata_piket-ы получим в итоге:
4б*(кол-во объявленных parray_piket-ов)+1кб*(кол-во объявленных parray_piket-ов)

piket_ked : array [1..10000] of Tdata_piket;
массив Tdata_piket-ов каждый из которых весит по килобайту (или около того) в итоге поимеем:
1кб*10000

В большинстве случаев второй вариант использует больше памяти, плюс не хотелось бы ограничивать себя с размерами массивов.
Вот такие вот у меня предпосылки.

к тому же мне бы еще хотелось чтобы объявление в Tdata_square

ked_square : array [1..kol_ked] of Tdata_ked;

тоже было без ограничения размера массива. Пробовал сразу, не вышло, теперь иду от более простого к более сложному :)

А ваше второе замечание будем пробовать.


 
icWasya   (2003-02-06 11:59) [8]

piket_ked : array [1..10000] of Tdata_piket;
массив Tdata_piket-ов каждый из которых весит по килобайту (или около того) в итоге поимеем:
1кб*10000
class в Delphi это уже указатель
так что
> прибавим память выделяемую на сами Tdata_piket-ы
ничего этого не будет


 
ghg   (2003-02-06 12:07) [9]

>DarkGreen © (06.02.03 11:35)
>1. inherited конструторы западло видать вызывать.

Create в Tobject не virtual.

> to all
В деструкторах поставил inhereted в конец.
Также вставил piket_ked[i]:=nil;
Все осталось также, вылетает AccessViolation.

С учетом исправлений конструкторы и деструкторы написаны правильно?


 
ghg   (2003-02-06 12:08) [10]

>icWasya © (06.02.03 11:59)
А что делать с ограничением размера массива?


 
Anatoly Podgoretsky   (2003-02-06 12:17) [11]

ghg (06.02.03 12:07)

Ну и что, что не virtual. Одно с другим не связано.



 
icWasya   (2003-02-06 12:18) [12]

что такое Tms_piket


 
icWasya   (2003-02-06 12:20) [13]


> А что делать с ограничением размера массива?

когда отладишь остальное, перепишешь на
piket_ked : array of ...


 
ghg   (2003-02-06 12:25) [14]

>icWasya © (06.02.03 12:18)
>что такое Tms_piket

array [1..200] of single


 
Романов Р.В.   (2003-02-06 12:26) [15]

ghg
А почему бы не использовать динамические массивы?


 
ghg   (2003-02-06 12:28) [16]

>1. inherited конструторы западло видать вызывать.

как это делать?


 
icWasya   (2003-02-06 12:37) [17]


>>1. inherited конструторы западло видать вызывать.

>как это делать?


имеется ввиду

constructor Tdata_square.Create;
var i : integer;
begin
inherited
......



но поскольну сонструктор у TObject ничего не делает, то в данном случае его можно не вызывать. Но для собльдения правил лучше inherited Create писать всегда


 
ghg   (2003-02-06 12:41) [18]

Дык он говорит что Create статический метод и не понимает что есть inherited


 
Anatoly Podgoretsky   (2003-02-06 12:42) [19]

Обманываешь


 
icWasya   (2003-02-06 12:46) [20]

короче у меня в таком виде компилится без ошибок и не ругается при удалении

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

const
kol_ked=100;
type
Sreda = array [1..50] of single;

type
TData_Piket = class
public
size_piket : integer;
File_name_piket, date_piket : shortstring;
x_piket, y_piket, z_piket : single;
Tms_piket : array [1..200] of single;
constructor Create;
end;

TData_Ked = class
public
kol_luch_ked, number_ked : integer;
angle_ked, radius_ked : array [1..8] of single;
piket_ked : array of TData_Piket;
constructor Create(nked : integer);
destructor Destroy; override;
end;

TData_square = class
public
Nt_square : integer;
map_square : Tbitmap;
kol_3d_color_square : integer;
rho_3d_square : array of single;
color_3d_square : array of Tcolor;
ked_square : array [1..kol_ked] of Tdata_ked;
constructor Create;
destructor Destroy; override;
end;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
square : Tdata_square;
ooo : file;
kol_3d_s, ked_s : integer;
piket_k : array [1..kol_ked] of integer;
Rho_square,H_square: array[ 1..3 ] of integer;

implementation

{$R *.DFM}

constructor Tdata_piket.Create;
begin
inherited Create;
size_piket:=2*200+75;
date_piket:="10.10.10";
File_name_piket:="00";
x_piket:=0; y_piket:=0; z_piket:=0;
end;

constructor Tdata_ked.Create(nked : integer);
var i : integer;
begin
inherited Create;
SetLength(piket_ked,piket_k[nked]+1);

for i:=1 to piket_k[nked] do
begin
piket_ked[i]:=Tdata_piket.Create;
end;
kol_luch_ked:=8; number_ked:=nked;
for i:= 1 to 8 do
begin
angle_ked[i]:=45*i; radius_ked[i]:=500;
end;
end;

destructor Tdata_ked.Destroy;
var i: integer;
begin
for i:=1 to piket_k[self.number_ked] do
begin
piket_ked[i].Free;
piket_ked[i]:=nil;
end;
SetLength(piket_ked,0);
inherited;
end;

constructor Tdata_square.Create;
var i : integer;
begin
inherited Create;
for i:=1 to kol_ked{ked_s} do
ked_square[i]:=TData_Ked.create(i);
setlength(rho_3d_square,kol_3d_s+1);
setlength(color_3d_square,kol_3d_s+1);
for i:=1 to kol_3d_s do
begin
color_3d_square[i]:=$00000000+i*$0000001a;
rho_3d_square[i]:=i*10;
end;
kol_3d_color_square:=kol_3d_s;
for i:=1 to 3 do
begin
Rho_square[i]:=i*10; H_square[i]:=i*10;
end;
map_square:=nil;
Nt_square:=length(ked_square[1].piket_ked[1].Tms_piket);
end;

destructor Tdata_square.Destroy;
var i : integer;
begin
map_square:=nil;
for i:=1 to kol_ked do ked_square[i].free;
setlength(rho_3d_square,0);
setlength(color_3d_square,0);
inherited;
end;

procedure TForm1.FormCreate(Sender: TObject);
var i : integer;
begin
ked_S:=0;
for i:=1 to kol_ked do piket_k[i]:=0;
piket_k[1]:=1;
piket_k[2]:=5;
piket_k[3]:=3;
piket_k[4]:=10;
kol_3d_s:=10;
square:=TData_square.create;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
FreeAndNil(square);
end;

end.



 
ghg   (2003-02-06 12:52) [21]

>Anatoly Podgoretsky © (06.02.03 12:42)
>Обманываешь

Правда обманываю. Сорри, как так получилось не знаю. :)

>icWasya © (06.02.03 12:46)

Спасибо. Дальше попробую разобраться.




Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2003.02.17;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.025 c
7-53310
Sanyok
2002-12-16 19:14
2003.02.17
Что такое серийный номер раздела винта?


3-52739
Avsam
2003-01-30 11:56
2003.02.17
Определение типа значения поля


3-52704
me2
2003-01-29 12:33
2003.02.17
Добавление столбцов к гриду в On-Line


9-52697
Fog
2002-09-12 12:14
2003.02.17
DDraw.dll


3-52786
Андрю-ХА!
2003-01-30 18:12
2003.02.17
TDBGrid.SelectedRows





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский