Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Access violation


Автор: AS-Web 29.11.2005, 21:07

Код

TLink=class
  InNode,ToNode: TPNode;
  Cost: Integer;
  procedure Draw(canvas: TCanvas);
  Constructor Create;
  Destructor free;
 end;
...
TNode=class
 private
  MinPath: integer;
  Links: TList;
  Checked: boolean;
  Shape: tshape;
  FLabel: tlabel;
  Number: integer;
  Tag: integer;
  FOwner: TPGraph;
  down:boolean;
  fstart: tpoint;
  //Procedure ShapeMosedown: TShape.
 public
  Procedure SetRoot;
  Procedure ResetChecker ;
  procedure ShapeMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
  procedure ShapeMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
  procedure ShapeMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
  Constructor Create(Owner: TPgraph;x,y:integer);
  property owner: TPGraph read fowner write fowner;
  Destructor Free;
 end;
...
{tgRAPH.CONNECT}
 temp:=tlink.Create;
 temp.InNode:=what;
 temp.ToNode:=self.root;
 temp.Cost:=cost;
 self.root^.Links.Add(@temp); <-Здесь self.root inaccessible

Подскажите, пожалуйста, почему могло произойти исключение?

Автор: Демо 29.11.2005, 21:14
А self - это что такое здесь?

Автор: CosmoMan 29.11.2005, 22:08
Цитата
А self - это что такое здесь?

Это такой специальный указатель, который передается
методу объекта при его вызове.

Я не понял.
Кода мало.
tgRAPH.CONNECT - что за процедура.

Код описания класса tgRAPH
Links.Add(@temp) - что за метод?

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

Автор: Bose 30.11.2005, 11:19
а сам по себе Self здесь определён?

Автор: AS-Web 30.11.2005, 11:57
А что, Self во внутренней процедуре класса бывает не определён? TGraph.Connect - это процедура аоединения двух объектов класса Tnode.
В свойство Links каждого заносится ссылка на другой.

Другой вопрос - почему если у меня есть переменная main: TGraph, то её адрес и адрес SElf во внутренней процедуре не совпадают

Автор: Alexeis 30.11.2005, 12:07
Цитата
self.root^.Links.Add(@temp);

надо self.root^.Links.Add(temp);

Автор: AS-Web 30.11.2005, 12:08
Так тоже не канает

Дело в том, что Self.root указывает не на ту переменную

Автор: Alexeis 30.11.2005, 12:15
Нужно больше кода smile

Автор: AS-Web 30.11.2005, 12:18
Тебе что конкретно дать?

Автор: Alexeis 30.11.2005, 12:23
Процедуру целиком с
Цитата

{tgRAPH.CONNECT}
temp:=tlink.Create;
temp.InNode:=what;
temp.ToNode:=self.root;
temp.Cost:=cost;
self.root^.Links.Add(@temp); <-Здесь self.root inaccessible

Автор: AS-Web 30.11.2005, 19:21
Код

procedure Tgraph.Connect(what: tpnode; Cost: integer);
var temp:TLink;
begin
 if what <>nil then
 begin
 temp:=tlink.Create;
 temp.InNode:=what;
 temp.ToNode:=self.root;
 temp.Cost:=cost;
 main.root^.Links.Add(@temp);
 what^.Links.Add(@temp);
 if not what^.I_O then //если в списке соединённых узлов
 begin
  fNotInGraph.Extract(what);
  FIngraph[what^.Number-1]:=@what;
 end;
 temp.Draw(main.root^.owner^.fcanvas);
 end;
end;

2 CosmoMam:
Код

function Tgraph.Add(x, y: integer): TPnode;
var curr:Tnode; temp: tpoint;
begin
 temp.x:=x;
 temp.y:=y;
 curr:=tnode.Create(@MAIN,twincontrol(owner).screentoclient(temp).x,twincontrol(owner).screentoclient(temp).y);
 FNotInGraph.Add(@curr);
 FIngraph.Add(nil);
 result:=@curr;
end;

procedure Tgraph.Connect(what: tpnode; Cost: integer);
var temp:TLink;
begin
 if what <>nil then
 begin
 temp:=tlink.Create;
 temp.InNode:=what;
 temp.ToNode:=self.root;
 temp.Cost:=cost;
 main.root^.Links.Add(@temp);
 what^.Links.Add(@temp);
 if not what^.I_O then
 begin
  fNotInGraph.Extract(what);
  FIngraph[what^.Number-1]:=@what;
 end;
 temp.Draw(main.root^.owner^.fcanvas);
 end;
end;

constructor Tgraph.Create(Owner: tcomponent;Canvas:Tcanvas);
begin
 root:=nil;
 fnumitems:=0;
 fFilename:='';
 self.owner:=owner;
 fcanvas:=Canvas;
 FNotInGraph:=tlist.Create;
 FInGraph:=tlist.Create;
end;

procedure Tgraph.DrawGraph;
var i,j: integer;
begin
 for i:=1 to FInGraph.Count-1 do
  for j:=1 to TPnode(FIngraph.Items[i])^.Links.Count-1 do
  begin
   TPLink(TPNode(FIngraph.Items[i])^.Links[j])^.Draw(canvas);
  end;
  for i:=1 to FNotInGraph.Count-1 do
  for j:=1 to TPnode(FNotInGraph.Items[i])^.Links.Count-1 do
  begin
   TPLink(TPNode(FNotInGraph.Items[i])^.Links[j])^.Draw(canvas);
  end;
end;

function TGraph.Extract: TPNode;
begin
 if self.Selected<>nil then
 begin;
  if self.selected^.I_O then
   self.FInGraph.Extract(self.selected)
  else
   self.FNotInGraph.Extract(self.selected);
   self.Selected^.Free;
   self.selected:=root;
 end;
end;

destructor TGraph.Free;
var i: integer;
begin
 for i:=1 to fingraph.Count-1 do
  if fingraph[i]<>nil then
   TPNOde(fingraph[i])^.Free;
 fingraph.Free;
 for i:=1 to fnotingraph.Count-1 do
  if fnotingraph[i]<>nil then
   TPNOde(fnotingraph[i])^.Free;
 FNotInGraph.Free;
end;

procedure Tgraph.LoadFromFile(s: string);
var f: file of byte;  curr: tnode;curr2: Tlink; i,j: integer;
begin
 assignfile(f,s);
 reset(f);
 read(f,fnumitems);
 {for i:=1 to fnumitems do
 begin
  curr:=tnode.Create;
  read(f,curr);
  for j:=1 to curr^.Links.Count do
  begin
   read(f,curr2);
   curr2
  end;
 end;   }
end;

procedure TGraph.ResetChecker;
var i: integer;
begin
if root <> nil then
 root.ResetChecker;
end;

procedure Tgraph.SaveToFile(s: string);
var f: file of TNode;   i: integer;
begin
 assignfile(f,s+'.dat');
 rewrite(f);
 for i:=0 to self.NumItems-1 do
  begin
   if self.FInGraph[i]
   write(f,self[]);
  end;
end; 


Тут не всё робит. Но всё-таки главный вопрос: почему self и переменная имеют разный адрес?

Автор: CosmoMan 30.11.2005, 22:04
Что такое main.root, было же self.root?
Можеш дать описание класса Tgraph с его переменными.
Может переделать все немного попроще, чтобы более ясно ошибку увидеть.

Автор: AS-Web 1.12.2005, 09:51
main.root - это как в программе объект обозначен.root: TPnode;

Автор: Alexeis 1.12.2005, 10:27
CosmoMan правельно требует - без класса Tgraph не разобраться.

Автор: CosmoMan 1.12.2005, 17:13
Main это то же самое, что и self?

Автор: AS-Web 1.12.2005, 19:02
Я и сам бы хотел это понять! Self - это ссылка на самого себя в коде класса, а main - это объект, объявленный в программе в её общей части.

Даю код Графа:
Код

 TGraph=class
 private
  fRoot: TPnode;
  FSelected: TPNode;
  FNumItems: byte;
  Ffilename: string;
  FCanvas: Tcanvas;
  Fowner:Tcomponent;
  FNotInGraph:tlist;
  FInGraph: tlist;
 public
  Procedure LoadFromFile(s: string);
  Procedure SaveToFile(s: string);
  Function Add(x,y: integer): TPnode;
  Function Extract: TPNode;
  Procedure Connect(what: tpnode;Cost:integer);
  Procedure DrawGraph;
  Procedure ResetChecker;
  Property NumItems: byte read FNumItems write  FNumItems;
  Property Canvas: TCanvas read Fcanvas write  Fcanvas;
  Property Owner: tcomponent read fowner write  fowner;
  Property Root: TPNode read fRoot write  FRoot;
  Property Selected: TPNode read fSelected write  FSelected;
  Constructor Create(Owner:Tcomponent;Canvas:Tcanvas);
  Destructor Free;
 end;

Автор: CosmoMan 1.12.2005, 20:39
Ооох...
Разбирался я, разбирался.
Мне так кажется, что это какойто компонент по работе с графикой.
Причем он частично закомпиляный. И тот код, который ты говориш - это код компонента. smile
Я не знаю, что там за код, но он все равно неполный. Я коечто попытался угадать.
Код

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Shape1: TShape;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

 TPNode = ^Links;

 TGraph = class
 private
  fRoot: TPNode;
  FSelected: TPNode;
  FNumItems: byte;
  Ffilename: string;
  FCanvas: Tcanvas;
  Fowner:Tcomponent;
  FNotInGraph:tlist;
  FInGraph: tlist;
 public
  Procedure LoadFromFile(s: string);
  Procedure SaveToFile(s: string);
  Function Add(x,y: integer): TPnode;
  Function Extract: TPNode;
  Procedure Connect(what: tpnode;Cost:integer);
  Procedure DrawGraph;
  Procedure ResetChecker;
  Property NumItems: byte read FNumItems write  FNumItems;
  Property Canvas: TCanvas read Fcanvas write  Fcanvas;
  Property Owner: tcomponent read fowner write  fowner;
  Property Root: TPNode read fRoot write  FRoot;
  Property Selected: TPNode read fSelected write  FSelected;
  Constructor Create(Owner:Tcomponent;Canvas:Tcanvas);
  Destructor Free;
 end;
  Links = class(TGraph); 

 TPGraph = class(TGraph);

 TNode=class
 private
  MinPath: integer;
  Links: TList;
  Checked: boolean;
  Shape: tshape;
  FLabel: tlabel;
  Number: integer;
  Tag: integer;
  FOwner: TPGraph;
  down:boolean;
  fstart: tpoint;
  //Procedure ShapeMosedown: TShape.
 public
  Procedure SetRoot;
  Procedure ResetChecker ;
  procedure ShapeMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
  procedure ShapeMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
  procedure ShapeMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
  Constructor Create(Owner: TPgraph;x,y:integer);
  //property owner: TPGraph read fowner write fowner;
  Destructor Free;
 end;

 TLink=class
  InNode,ToNode: TPNode;
  Cost: Integer;
  procedure Draw(canvas: TCanvas);
  Constructor Create;
  Destructor free;
 end;


var
  Form1: TForm1;

implementation

{$R *.dfm}

function Tgraph.Add(x, y: integer): TPnode;
var curr:Tnode; temp: tpoint;
begin
 temp.x:=x;    
 temp.y:=y;
 curr:=tnode.Create(@self,twincontrol(owner).screentoclient(temp).x,twincontrol(owner).screentoclient(temp).y);
 FNotInGraph.Add(@curr);
 FIngraph.Add(nil);    
 result:=@curr;    
end;


procedure Tgraph.Connect(what: tpnode; Cost: integer);    
var temp:TLink;    
begin    
 if what <>nil then    
 begin    
 temp:=tlink.Create;
 temp.InNode:=what;    
 temp.ToNode:=self.root;
 temp.Cost:=cost;
 //self.root^.
 self.root^.Links.Add(@temp);       //<-Caanu self.root inaccessible
 what^.Links.Add(@temp);
 if not what^.I_O then
 begin    
  fNotInGraph.Extract(what);    
  FIngraph[what^.Number-1]:=@what;    
 end;    
 temp.Draw(main.root^.owner^.fcanvas);    
 end;    
end;


constructor Tgraph.Create(Owner: tcomponent;Canvas:Tcanvas);    
begin    
 root:=nil;    
 fnumitems:=0;    
 fFilename:='';    
 self.owner:=owner;    
 fcanvas:=Canvas;    
 FNotInGraph:=tlist.Create;    
 FInGraph:=tlist.Create;    
end;

procedure Tgraph.DrawGraph;    
var i,j: integer;    
begin    
 for i:=1 to FInGraph.Count-1 do    
  for j:=1 to TPnode(FIngraph.Items[i])^.Links.Count-1 do    
  begin    
   TPLink(TPNode(FIngraph.Items[i])^.Links[j])^.Draw(canvas);    
  end;    
  for i:=1 to FNotInGraph.Count-1 do    
  for j:=1 to TPnode(FNotInGraph.Items[i])^.Links.Count-1 do    
  begin    
   TPLink(TPNode(FNotInGraph.Items[i])^.Links[j])^.Draw(canvas);    
  end;    
end;

function TGraph.Extract: TPNode;    
begin    
 if self.Selected<>nil then    
 begin;    
  if self.selected^.I_O then    
   self.FInGraph.Extract(self.selected)    
  else    
   self.FNotInGraph.Extract(self.selected);    
   self.Selected^.Free;    
   self.selected:=root;    
 end;    
end;

destructor TGraph.Free;    
var i: integer;    
begin    
 for i:=1 to fingraph.Count-1 do    
  if fingraph[i]<>nil then    
   TPNOde(fingraph[i])^.Free;    
 fingraph.Free;    
 for i:=1 to fnotingraph.Count-1 do    
  if fnotingraph[i]<>nil then    
   TPNOde(fnotingraph[i])^.Free;    
 FNotInGraph.Free;    
end;


procedure Tgraph.LoadFromFile(s: string);    
var f: file of byte;  curr: tnode;curr2: Tlink; i,j: integer;    
begin    
 assignfile(f,s);    
 reset(f);    
 read(f,fnumitems);    
 {for i:=1 to fnumitems do    
 begin    
  curr:=tnode.Create;    
  read(f,curr);    
  for j:=1 to curr^.Links.Count do
  begin    
   read(f,curr2);    
   curr2    
  end;    
 end;   }    
end;

procedure TGraph.ResetChecker;    
var i: integer;    
begin    
if root <> nil then    
 root.ResetChecker;    
end;    
procedure Tgraph.SaveToFile(s: string);    
var f: file of TNode;   i: integer;    
begin    
 assignfile(f,s+'.dat');    
 rewrite(f);    
 for i:=0 to self.NumItems-1 do    
  begin    
   if self.FInGraph[i]    
   write(f,self[]);    
  end;    
end;

end.



Того, что ты дал недостаточно.

Автор: Alexeis 2.12.2005, 11:31
TPNode = ^Links; - излишне так как TLink=class и переменная объекта этого класса и есть указатель на объект фактически TPNode указывает на адрес по которому хранится указатель который в свою очередь указывает на объект типа TLink. Здесь и зарыта собака так что надо переделать код по нормальному.

Автор: CosmoMan 2.12.2005, 19:44
Да ты мне код полностию дать можеш!? Я же не экстрасенс.
На мыло мне вышли в конце концов, если это такой секрет.

Автор: AS-Web 5.12.2005, 11:50
alexeis1 Спасибо. Я сам дня три назад тоже smile дошёл.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)