Форум: "Основная";
Текущий архив: 2002.12.23;
Скачать: [xml.tar.bz2];
ВнизКлассы и обьекты Найти похожие ветки
← →
OlegL (2002-12-04 11:23) [0]Help me please! Подскажите пожайлуста где я допустил ошибку
type
PList=^AList;
AList=record
x1:integer;
y1:integer;
end;
TArcas=class
private
pl_cut:TList;
rec:PList;
h,w:integer;
public
height,width:integer;
constructor create(bit:TBitmap);
procedure move;
destructor destroy;override;
end;
...
constructor TArcas.create(bit:TBitmap);
var j,i:integer;
begin
pl_cut:=TList.Create; Тут даёт ошибку "Acces violation at adress...."
h:=round(bit.Height/8);
w:=round(bit.Width/5);
for i:=0 to round(bit.Height/h)-1 do
for j:=0 to round(bit.Width/w)-1 do
begin
new(rec);
rec^.x1:=i*height;
rec^.y1:=j*width;
pl_cut.Add(rec);
end;
Dispose(rec);
end;
Конструктор я вызывыю в другом юните (если это важно)
← →
Skier (2002-12-04 11:28) [1]>OlegL
constructor TArcas.create(bit:TBitmap);
var j,i:integer;
begin
inherited Create;
//...........
end;
← →
Skier (2002-12-04 11:32) [2]>OlegL
И со сладкой парочкой new(rec); - Dispose(rec);
у тебя не всё в порядке...
for j:=0 to round(bit.Width/w)-1 do
begin
new(rec);
rec^.x1:=i*height;
rec^.y1:=j*width;
pl_cut.Add(rec);
end;
Dispose(rec); //зачем ?
Освобождай записи в pl_cut через него же : в цикле...
← →
OlegL (2002-12-04 11:46) [3]Спасибо
← →
VaS (2002-12-04 11:58) [4]inherited Create не нужно.
В остальном Skier прав.
← →
Skier (2002-12-04 12:12) [5]>VaS
> inherited Create не нужно.
Угу. Необязательно...
← →
OlegL (2002-12-10 11:35) [6]Тогда что нужно? С ним или без него всё равно не едёт.
А насчёт указателя я сделал так:
for j:=0 to round(bit.Width/w)-1 do
begin
new(rec);
rec^.x1:=i*height;
rec^.y1:=j*width;
pl_cut.Add(rec);
rec:=nil;
Dispose(rec);
end;
вроде правильно (по краиней мере в другом юните работает :-)))
← →
Skier (2002-12-10 11:41) [7]>OlegL
Объясни-ка мне такую вещь :
Зачем ты добавляешь дин. структуру (rec)
в список (pl_cut) и затем её тут же освобождаешь...,вернее
пытаешься освободить, т.к. перед освобождением ты ещё и
сбрасываешь указатель (rec:=nil) ?!
"Я понять тебя хочу, смысла я в тебе ищу..."
← →
OlegL (2002-12-10 11:50) [8]Тогда что нужно? С ним или без него всё равно не едёт.
А насчёт указателя я сделал так:
for j:=0 to round(bit.Width/w)-1 do
begin
new(rec);
rec^.x1:=i*height;
rec^.y1:=j*width;
pl_cut.Add(rec);
rec:=nil;
Dispose(rec);
end;
вроде правильно (по краиней мере в другом юните работает :-)))
← →
VaS (2002-12-10 12:11) [9]
for j:=0 to Round(bit.Width/w)-1 do
begin
//выделили память. rec хранит указатель на нее
New(rec);
rec.x1:=i*Height;
rec.y1:=j*Width;
//добавили в список указатель на ту память
pl_cut.Add(rec);
//очистили переменную rec. память не очищена.
//если бы не указатель в списке, то освободить память мы бы не смогли никогда
rec:=nil;
//очищаем память по адресу 0. По этому адресу по соглашению
//ничего быть не может.
Dispose(rec);
end;
При уничтожении списка нужно таки освободить память:
for i:=0 to pl_cut.Count-1 do
if pl_count <> nil then
Dispose(pl_count[i]);
← →
OlegL (2002-12-10 12:23) [10]Это не самая большая моя проблема (с указателями), я не могу справиться с конструктором.
Я же записиваю его в pl_cut потом освобождаю. Я пытался делать Dispose(rec) без rec:=nil и не работало (всё это работает в другом месте, в другом юните). Может я и не прав но ведь работает :-)
← →
VaS (2002-12-10 12:36) [11]Ты случаем свой тип TList не определил?! Если да, переименовывай немедленно (либо везде пиши Classes.TList). Да и PList, AList не особо интуитивно понятны.
← →
Skier (2002-12-10 12:43) [12]PList=^AList;
AList=record
x1:integer;
y1:integer;
end;
TArcas=class
private
pl_cut:TList;
rec:PList;
h,w:integer;
public
height,width:integer;
constructor create(bit:TBitmap);
procedure move;
destructor destroy;override;
end;
//....................
constructor TArcas.create(bit: TBitmap);
var
j,i:integer;
begin
inherited Create;
pl_cut:=TList.Create;
if bit <> nil then begin
h:=round(bit.Height/8);
w:=round(bit.Width/5);
for i:=0 to round(bit.Height/h)-1 do begin
for j:=0 to round(bit.Width/w)-1 do begin
new(rec);
rec^.x1:=i*height;
rec^.y1:=j*width;
pl_cut.Add(rec);
end; //for j
end; //for i
end; //if
end;
destructor TArcas.destroy;
var
i : integer;
begin
for i:=0 to pl_cut.Count-1 do begin
if pl_cut[i] <> nil then begin
Dispose(pl_cut[i]);
pl_cut[i] := nil;
end; //if
end; //for
FreeAndNil(pl_cut);
inherited destroy;
end;
← →
OlegL (2002-12-11 09:51) [13]В данном случае прав VaS, потому что я всё равно храню все эти указатели в списке pl_cut, зачем мне не уничтажать его после добавления, а списсок я освобождаю в деструкторе (да в любом случае, у меня же работает в Unit1). Проблема у меня в Unit2, сдесь у меня не выполняется ничего (ни pl_cut:=TList.Create ни
ни всё остальное) в теле
constructor Create(..);
..
begin
...//тут
end;
с inherited или без, может ещё что-то нужно добовить?
← →
Skier (2002-12-11 10:16) [14]>OlegL
Так долго можно гадать...
Убери ссылки (в uses) на остальные свои модули (если они есть) в Unit1 и Unit2 и попробуй поиграться, если не получится, то код
Unit1 и Unit2 выкладывай сюда полностью...
← →
Anatoly Podgoretsky (2002-12-11 10:28) [15]OlegL © (04.12.02 11:23)
Конструктор я вызывыю в другом юните (если это важно)
Важно, но сам вызов
И вот это лишнее Dispose(rec);, ты же так удаляешь последнюю добавленную записиь.
← →
OlegL (2002-12-11 11:13) [16]вот код обеих юнитов:
тут работает всё прекрасно...
unit Unit1;
interface
uses
..,Unit2;
type
PList=^AList;
AList=record
x1:integer;
y1:integer;
end;
TMap=class
private
mapa:TList;
rec:PList;
public
Height,Width:integer;
constructor Create(bit:TBitmap;X,Y:integer);
procedure Draw(Ecran:TRect;bit:TBitmap;buff:TBitmap);
destructor Destroy;override;
end;
TForm1 = class(TForm)
..
..
..
end;
var
Form1: TForm1;
a,MouseX,MouseY:integer;
Ecran:TRect;
Buffer:TBitmap;
carcas,map_bit:TBitmap;
Arc:TBitmap;
pat1,pat2:TRect;
ScrollCount,sp_hw:integer;
Harta:TMap;
Arcas:TArcas;
implementation
{$R *.dfm}
constructor TMap.Create(bit:TBitmap;X,Y:integer);
var j,i:integer;
begin
mapa:=TList.Create;
for i:=0 to round(bit.Height/sp_hw)-1 do
for j:=0 to round(bit.Width/sp_hw)-1 do
begin
new(rec);
rec^.x1:=i*sp_hw;
rec^.y1:=j*sp_hw;
mapa.Add(rec);
rec:=nil;
Dispose(rec);
end;
Width:=X;
Height:=Y;
end;
procedure TMap.Draw(Ecran:TRect;bit:TBitmap;buff:TBitmap);
var buf_x,buf_y,w,X1,Y1,X2,Y2,I,J:integer;
Index:PList;
begin
if Ecran.Left<0 then exit;
if Ecran.Top<0 then exit;
if Ecran.Right>Width then exit;
if Ecran.Bottom>Height then exit;
w:=round(bit.Width/sp_hw)-1;
X1:=round(Ecran.Left/sp_hw);
Y1:=round(Ecran.Top/sp_hw);
X2:=X1+round((Ecran.Right/sp_hw));
Y2:=Y1+round((Ecran.Bottom/sp_hw));
buf_x:=0;
for i:=X1 to X2 do
begin
buf_y:=0;
for j:=Y1 to Y2 do
begin
a:=(i+j)+(i*w);
if a>(bit.Width/sp_hw)*(bit.Height/sp_hw)-1 then exit;
index:=(mapa.Items[a]);
BitBlt(buff.Canvas.Handle,buf_x,buf_y,sp_hw,sp_hw,bit.Canvas.Handle,Index^.x1,Index^.y1,SRCCopy);
inc(buf_y,sp_hw);
end;
inc(buf_x,sp_hw);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
map_bit:=TBitmap.Create;
map_bit.LoadFromFile("res\map.bmp");
sp_hw:=round(map_bit.Height/50);
carcas:=TBitmap.Create;
carcas.LoadFromFile("res\carcas.bmp");
arc:=TBitmap.Create;
arc.LoadFromFile("res\Arcas.bmp");
Arcas.create(arc);
Ecran.Top:=0;
Ecran.Left:=0;
Ecran.Right:=Form1.Width;
Ecran.Bottom:=Form1.Height;
Buffer:=TBitmap.Create;
Buffer.Height:=DXDraw1.Height;
Buffer.Width:=DXDraw1.Width;
Harta:=TMap.Create(map_bit,map_bit.Width,map_bit.Height);
DXDraw1.ColorTable := DXImageList1.Items.ColorTable;
DXDraw1.DefColorTable := DXImageList1.Items.ColorTable;
DXDraw1.UpdatePalette;
DXDraw1.Cursor:=crNone;
DXTimer1.Enabled:=true;
ScrollCount:=sp_hw;
end;
procedure TForm1.DXDraw1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
MouseX:=X;
MouseY:=Y;
if MouseX<sp_hw/2 then
begin
dec(Ecran.Left,ScrollCount);
if Ecran.Left<0 then
Ecran.Left:=0
else
dec(Ecran.Right,ScrollCount);
end;
if MouseX>DXDraw1.Width-sp_hw/2 then
begin
inc(Ecran.Right,ScrollCount);
if Ecran.Right>Harta.Width then
Ecran.Right:=Harta.Width
else
inc(Ecran.Left,ScrollCount);
end;
if MouseY<sp_hw/2 then
begin
dec(Ecran.Top,ScrollCount);
if Ecran.Top<0 then
Ecran.Top:=0
else
dec(Ecran.Bottom,ScrollCount);
end;
if MouseY>DXDraw1.Height-sp_hw/2 then
begin
inc(Ecran.Bottom,ScrollCount);
if Ecran.Bottom>Harta.Height then
Ecran.Bottom:=Harta.Height
else
inc(Ecran.Top,ScrollCount);
end;
end;
procedure TForm1.DXTimer1Timer(Sender: TObject; LagCount: Integer);
begin
Arcas.move;
Harta.Draw(Ecran,map_bit,buffer);
DXDraw1.Surface.LoadFromGraphic(buffer);
DXImageList1.Items[1].Draw(DXDraw1.Surface,0,0,0);
DXImageList1.Items[0].Draw(DXDraw1.Surface,MouseX,MouseY,0);
DXDraw1.Flip;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Harta.Destroy;
map_bit.Free;
buffer.Free;
carcas.Free;
end;
destructor TMap.Destroy;
var i:integer;
begin
for i:=0 to mapa.Count-1 do
begin
mapa[i]:=nil;
dispose(mapa[i]);
end;
Inherited Destroy;
end;
end.
.. а тут нет
unit Unit2;
interface
uses Classes,Windows, Graphics;
type
PList=^AList;
AList=record
x1:integer;
y1:integer;
end;
TArcas=class
private
pl_cut:TList;
rec:PList;
h,w:integer;
height,width:integer;
public
constructor Create(bit:TBitmap);
procedure move;
destructor destroy;override;
end;
implementation
constructor TArcas.Create(bit:TBitmap);
var j,i:integer;
begin
inherited create;
pl_cut:=TList.Create;
h:=round(bit.Height/8);
w:=round(bit.Width/5);
for i:=0 to round(bit.Height/h)-1 do
for j:=0 to round(bit.Width/w)-1 do
begin
new(rec);
rec^.x1:=i*height;
rec^.y1:=j*width;
pl_cut.Add(rec);
rec:=nil;
Dispose(rec);
end;
end;
procedure TArcas.move;
begin
..не доделал
end;
destructor TArcas.destroy;
begin
.. не доделал
end;
end.
← →
Skier (2002-12-11 11:17) [17]Что за ерудна ?!
for i:=0 to mapa.Count-1 do
begin
mapa[i]:=nil;
dispose(mapa[i]);
end;
← →
OlegL (2002-12-11 11:42) [18]Давайте оставим это в покои, с этим я потом разберусь (допустим этого нету). Помогите лучше с конструктором.
constructor TArcas.Create(bit:TBitmap);
var j,i:integer;
begin
inherited create;
pl_cut:=TList.Create;
h:=round(bit.Height/8);
w:=round(bit.Width/5);
for i:=0 to round(bit.Height/h)-1 do
for j:=0 to round(bit.Width/w)-1 do
begin
new(rec);
rec^.x1:=i*height;
rec^.y1:=j*width;
pl_cut.Add(rec);
rec:=nil;
Dispose(rec);
end;
end;
← →
Skier (2002-12-11 11:47) [19]>OlegL
Давайте...
Тогда прокомментируйте вот этот фрагмент, вернее его
логику :
new(rec);
//.....
pl_cut.Add(rec);
rec:=nil;
Dispose(rec);
← →
Fantasist (2002-12-12 08:19) [20]Ну ошибка то в каком месте?! Я так прочитал:
> pl_cut:=TList.Create; Тут даёт ошибку "Acces violation
> at adress...."
чуть челюсть не выронил, думаю: нифига себе ошибочки изобретаются, прямо при попытки создания TList в конструкторе! Тут надо изобретательство проявить, чтобы там AV получилось.
А вообще коли ты с указателями занимаешься, то я бы посоветывал бы заменить эту вещь:
> type
> PList=^AList;
> AList=record
> x1:integer;
> y1:integer;
> end;
На
PList=class
x1:integer;
y1:integer;
constructor Create(aX:integer=0;aY:integer=0);
end;
Проще будет и читабельнее.
Вместо всего этого:
> new(rec);
> rec^.x1:=i*height;
> rec^.y1:=j*width;
> pl_cut.Add(rec);
> rec:=nil;
пишишь:
pl_cut.Add(PList.Create(i*height,j*width);
Работать с такими указателями гораздо проще.
Потом и стандартным FreeList освободить легко. Это который:
procedure FreeList(var List:TList);
var
i:integer;
begin
if List=nil then exit;
for i:=0 to List.Count-1 do
TObject(List[i]).Free;
List.Free;
List:=nil;
end;
Ну и ClearList тоже.
← →
OlegL (2002-12-12 09:09) [21]Skier ©
новый(rec)
добавить в pl_cut rec
rec анулировать
и освободить (в pl_cut остаётся как раз то что мне нужно) :-)))
Fantasist ©
дело в том что между begin и end не только это (pl_cut:=TList.Create;) не работатет но и всё остальное (даже присваивание).
А на счёт pointer-а, я делал и так как ты предложил, и двумя другими способами, но мне кажеться что так лучше (опять же, может я и не прав :-))))
← →
VaS (2002-12-12 10:40) [22]Arcas.create(arc) замяняем на Arcas:=TArcas.Create(arc).
Мама дорогая...
← →
Fantasist (2002-12-12 21:34) [23]
> VaS © (12.12.02 10:40)
> Arcas.create(arc) замяняем на Arcas:=TArcas.Create(arc).
Во класс! Я правда код не читал, но прочитал соседнюю ветку, и решил, что здесь наверняк та же самая проблема (именно не правилное создание). Самое главное человек такой хитрый пишит: List:=TList.Create - я думал, ну с этим значит все в порядке - как конструировать объекты он уже знает... Оказывается знает только наполовину...
И что меня поражает какие они умные! Лезут дебаггером внутрь конструкторов и выясняют, что ошибка там. Я когда начинал, тоже вначале написал типа: MyObj.Create - но тут вывалился AV, и я решил, что это строчка не правильная. Лезть дебаггером внутрь конструктора, у меня ума не хватило. :)
← →
OlegL (2002-12-13 08:57) [24]:-))) Спасибо!
> VaS © (12.12.02 10:40)
> Arcas.create(arc) замяняем на Arcas:=TArcas.Create(arc).
> Мама дорогая...
:-)) Полгода назад я точно также хотел создать какой-то Bitmap и мне колега по работе обяснил что никогда так не надо делать :-))) а сейчас опять ..... просто механически получилось :-))))
> Самое главное человек такой хитрый пишит: List:=TList.Create
> - я думал, ну с этим значит все в порядке - как конструировать
> объекты он уже знает... Оказывается знает только наполовину...
:-))) Да знаю я. Всё механически получилось
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.12.23;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.007 c