如果释放二维字符数组,FreePascal 中会出现运行时错误 216

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

我创建一个

Pointer
到二维
Char
Array
,用井号(
#
)填充它,将其输出到控制台并释放指针的内存。如果我使用
Dispose()
,则会弹出运行时错误 216。如果我不使用
Dispose()
一切都会正常。这是为什么?

program GridShower;

type
    Grid = array [1..14, 1..28] of char;
    GridPtr = ^Grid;

const
    LinesNum = 14;
    ColumnsNum = 28;

function FillGrid(CurGrid: GridPtr): GridPtr;
var
    i, j: integer;
begin
    for i := 0 to LinesNum - 1 do
    begin
        for j := 0 to ColumnsNum - 1 do
        begin
            CurGrid^[i][j] := '#';
        end;
    end;
    FillGrid := CurGrid;
end;

procedure ShowGrid(CurGrid: GridPtr);
var
    i, j: integer;
begin
    for i := 0 to LinesNum - 1 do
    begin
        for j := 0 to ColumnsNum - 1 do
        begin
            write(CurGrid^[i][j]);
        end;
        write(#10); { newline char in ASCII }
    end;
end;

{ MAIN PROGRAM }

var
    CurGrid: GridPtr;
begin
    new(CurGrid);
    CurGrid := FillGrid(CurGrid);
    ShowGrid(CurGrid);
    dispose(CurGrid);
end.
pointers freepascal off-by-one
1个回答
0
投票

如果您声明

Array
数据类型:

type
  Grid = array [1..14, 1..28] of char;

然后你也have分别迭代元素

1
14
1
28
。 你的循环:

  for i := 0 to LinesNum - 1 do
  begin
      for j := 0 to ColumnsNum - 1 do
      begin
          { … } CurGrid^[i][j] { … }
      end;
  end;

访问

CurGrid^[0][0]
CurGrid^[0][1]
、…
CurGrid^[1][0]
不存在(因为您声明了从
1
开始的维度)并且忘记访问末尾的
Array
元素(
14
28
取决于我们谈论的是哪个维度)。这非常不好。

通过这样做,您可能会覆盖放置在指针内存前面的一些重要数据,因此

Dispose()
变得混乱。

改为:

const
  LinesNum= 14;
  ColumnsNum= 28;
type
  // That's the very point of constants: using them EVERYwhere.
  Grid= Array [1.. LinesNum, 1.. ColumnsNum] of Char;

...

  // Choose better variable names; loop from 1.. LinesNum.
  for Line:= 1 to LinesNum do begin
    for Column:= 1 to ColumnsNum do begin
© www.soinside.com 2019 - 2024. All rights reserved.