Pascal 中的外部访问冲突 - 它来自哪里?

问题描述 投票:0回答:1

当我尝试运行这段代码时:

program Version_als_Kompilett;

uses SysUtils;

type
  tRefBinBaum = ^tBinBaum;
  tBinBaum = record
    wert: integer;
    li: tRefBinBaum;
    re: tRefBinBaum
  end;

  function initTree(): tRefBinBaum;
  var 
    Baum: tRefBinBaum;
  begin
    new(Baum);
    Baum^.wert := 30; //random(100);

    if (Baum = nil)         then writeln('Baum ist nil');
    if (Baum^.li = nil)     then writeln ('Baum links nil')        else writeln('Baum links                : ' + IntToStr(Baum^.li^.wert));
    if (Baum^.re = nil)     then writeln('Baum rechts nil')        else writeln('Baum rechts        : ' + IntToStr(Baum^.re^.wert));
    if (Baum^.li^.li = nil) then writeln('Baum links links nil')   else writeln('Baum links links   : ' + IntToStr(Baum^.li^.li^.wert));
    if (Baum^.li^.re = nil) then writeln('Baum links rechts nil')  else writeln('Baum links rechts  : ' + IntToStr(Baum^.li^.re^.wert));
    if (Baum^.re^.li = nil) then writeln('Baum rechts links nil')  else writeln('Baum rechts links  : ' + IntToStr(Baum^.re^.li^.wert));
    if (Baum^.re^.re = nil) then writeln('Baum rechts rechts nil') else writeln('Baum rechts rechts : ' + IntToStr(Baum^.re^.re^.wert));

    initTree := Baum;
  end;

var
  Testsubjekt: tRefBinBaum;

begin
  Testsubjekt := initTree();

  readln();
end.

我得到这个结果:

enter image description here

这行代码产生了问题:

if (Baum^.re = nil)     then writeln('Baum rechts nil')             else writeln('Baum rechts        : ' + IntToStr(Baum^.re^.wert));
  1. 为什么会这样?左子节点似乎有效,但右子节点无效。
  2. 我该如何解决?我是 Object - Pascal 的新手。

我尝试过各种 if - 语句。然后我创建了这个小的可编译代码。我正在使用 Lazarus 作为 IDE。

翻译:“Baum”在英语中的意思是“树”,“Wert”是“价值”,“rechts”是“右”,“链接”是“左”。

pascal access-violation
1个回答
0
投票

用FPC编译你的程序,然后运行它:

% fpc Version_als_Kompilett.pas 
Free Pascal Compiler version 3.2.2 [2021/10/28] for x86_64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Darwin for x86_64
Compiling Version_als_Kompilett.pas
Version_als_Kompilett.pas(37,3) Note: Local variable "Testsubjekt" is assigned but never used
Assembling version_als_kompilett
Linking Version_als_Kompilett
44 lines compiled, 0.7 sec
1 note(s) issued
% ./Version_als_Kompilett 
Baum links nil
Baum rechts nil
An unhandled exception occurred at $00000001054B9130:
EAccessViolation: Access violation
  $00000001054B9130

如果

li
字段和
re
Baum
字段都是
nil
,并且您的输出显示它们是 are,那么访问这些字段将导致您的内存访问冲突重新看到。

这个可以用更简单的程序看出来

program test;
type
  tptr = ^t;
  t = record 
    v : integer;
    p : tptr;
  end;
var
  x : tptr;
begin
  new(x);
  if x^.p = nil then writeln('is nil');
  if x^.p^.p = nil then writeln('nil and nil');
end.
% fpc test.pas 
Free Pascal Compiler version 3.2.2 [2021/10/28] for x86_64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Darwin for x86_64
Compiling test.pas
Assembling test
Linking test
14 lines compiled, 0.2 sec
% ./test
is nil
Runtime error 216 at $000000010CD629DB
  $000000010CD629DB
© www.soinside.com 2019 - 2024. All rights reserved.