如何解决Delphi:在运行时出现访问冲突错误
我对Delphi来说还很陌生,我正尝试使用不同的单元来存储TList和TObject,以及根据以前的组合框选择生成其他组合框选项。运行后,我立即收到以下错误消息:
Project Project1.exe引发带有消息的异常类$ C0000005 '在0x004087d7发生访问冲突:读取地址0x00000000
模块'Project1.exe'中地址00408813的访问冲突。阅读 地址00000000。
我已经跟踪了调试工具中的步骤,但是看不到为什么它不起作用。我已经搜索了这个问题,并找到了一些解决方案,但似乎没有什么适用于我当前的问题。
unit MainForm;
interface
uses
Winapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,Vcl.Controls,Vcl.Forms,Vcl.Dialogs,Vcl.StdCtrls;
type
TfMain = class(TForm)
lcpu: TLabel;
cbcpu: TComboBox;
lGPU: TLabel;
cbGPU: TComboBox;
lmotherboard: TLabel;
cbmotherboard: TComboBox;
lRAM: TLabel;
cbRAM: TComboBox;
eCompatible: TEdit;
lCompatible: TLabel;
eCost: TEdit;
lCost: TLabel;
Label11: TLabel;
lbcpu: TListBox;
lbmotherboard: TListBox;
lbGPU: TListBox;
lbRAM: TListBox;
procedure FormShow(Sender: TObject);
procedure cbcpuChange(Sender: TObject);
private
{ Private declarations }
public
// procedure cbcpupopulate();
end;
type TGPU = class(TObject)
public
name : string;
vram : integer;
clock : integer;
price : string;
end;
type Tcpu = class(TObject)
public
name : string;
cores : integer;
clock : real;
intel : boolean;
amd : boolean;
price : string;
end;
type TMobo = class(TObject)
public
name : string;
intel : boolean;
amd : boolean;
price : string;
end;
type TRAM = class(TObject)
public
name : string;
memory : integer;
clock : integer;
price : string;
end;
var
fMain: TfMain;
implementation
{$R *.dfm}
uses cpus,GPUs,motherboards;
procedure TfMain.cbcpuChange(Sender: TObject);
var
i : integer;
mobo : TMobo;
begin
if Tcpu(fMain.cbcpu.ItemIndex).intel = true then begin
for i := 0 to motherboards.MoboPartsList.Count-1 do begin
mobo := TMobo(motherboards.MoboPartsList.Items[i]);
if mobo.intel = true then begin
fMain.cbmotherboard.Items.Addobject(mobo.name,mobo);
end;
end;
end;
end;
procedure cbcpupopulate();
var
i : integer;
cpu : Tcpu;
begin
for i := 0 to cpus.cpuPartsList.Count-1 do begin
cpu := Tcpu(cpus.cpuPartsList.Items[i]);
fMain.cbcpu.Items.Addobject(cpu.name,cpu);
end;
end;
procedure TfMain.FormShow(Sender: TObject);
begin
motherboards.MakeMoboList;
cpus.MakecpuList();
GPUs.popgpulist();
cbcpupopulate;
end;
end.
解决方法
在cbCPUChange()
中,您错误地访问了TCPU
对象。
表达式TCPU(fMain.cbCPU.ItemIndex)
正在将列表索引类型转换为对象指针。您需要使用ItemIndex
来访问ComboBox的Objects[]
属性,该属性由TCPU
用cbCPUpopulate()
个对象填充。
此外,也不需要从fMain
类的方法内部使用TfMain
全局变量。改用该方法的隐式Self
指针。
尝试更多类似的方法:
procedure TfMain.cbCPUChange(Sender: TObject);
var
i : integer;
mobo : TMobo;
begin
cbMotherboard.Items.BeginUpdate;
try
cbMotherboard.Items.Clear;
i := cbCPU.ItemIndex;
if i < 0 then Exit;
if TCPU(cbCPU.Items.Objects[i]).intel then begin
for i := 0 to Motherboards.MoboPartsList.Count-1 do begin
mobo := TMobo(Motherboards.MoboPartsList.Items[i]);
if mobo.intel then begin
cbMotherboard.Items.AddObject(mobo.name,mobo);
end;
end;
end;
finally
cbMotherboard.Items.EndUpdate;
end;
end;
另一方面,TCPU
,TMobo
和TRAM
类型的声明不属于MainForm
单元。应该在实际创建这些类型的对象列表的其他单元中声明它们,例如:TCPU
单元中的CPUs
,TMobo
单元中的Motherboards
等:
unit MainForm;
interface
uses
Winapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,Vcl.Controls,Vcl.Forms,Vcl.Dialogs,Vcl.StdCtrls;
type
TfMain = class(TForm)
lCPU: TLabel;
cbCPU: TComboBox;
lGPU: TLabel;
cbGPU: TComboBox;
lMotherboard: TLabel;
cbMotherboard: TComboBox;
lRAM: TLabel;
cbRAM: TComboBox;
eCompatible: TEdit;
lCompatible: TLabel;
eCost: TEdit;
lCost: TLabel;
Label11: TLabel;
lbCPU: TListBox;
lbMotherboard: TListBox;
lbGPU: TListBox;
lbRAM: TListBox;
procedure FormShow(Sender: TObject);
procedure cbCPUChange(Sender: TObject);
private
{ Private declarations }
procedure cbCPUpopulate;
public
end;
var
fMain: TfMain;
implementation
{$R *.dfm}
uses
CPUs,GPUs,Motherboards;
procedure TfMain.cbCPUChange(Sender: TObject);
var
i : integer;
mobo : Motherboards.TMobo;
begin
cbMotherboard.Items.BeginUpdate;
try
cbMotherboard.Items.Clear;
i := cbCPU.ItemIndex;
if i < 0 then Exit;
if CPUs.TCPU(cbCPU.Items.Objects[i]).intel then begin
for i := 0 to Motherboards.MoboPartsList.Count-1 do begin
mobo := Motherboards.TMobo(Motherboards.MoboPartsList.Items[i]);
if mobo.intel then begin
cbMotherboard.Items.AddObject(mobo.name,mobo);
end;
end;
end;
finally
cbMotherboard.Items.EndUpdate;
end;
end;
procedure TfMain.cbCPUpopulate;
var
i : integer;
CPU : CPUs.TCPU;
begin
for i := 0 to CPUs.CPUPartsList.Count-1 do begin
CPU := CPUs.TCPU(CPUs.CPUPartsList.Items[i]);
cbCPU.Items.AddObject(CPU.name,CPU);
end;
end;
procedure TfMain.FormShow(Sender: TObject);
begin
Motherboards.MakeMoboList;
CPUs.MakeCPUList;
GPUs.popgpulist;
cbCPUpopulate;
end;
end.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。