使用 SetLength() 时出现访问冲突

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

我正在使用 Pascal 编写一个 connect4 游戏来完成作业。默认情况下,它会创建一个大小为 6x7 且获胜长度等于 4 的棋盘,但是它也可以传递参数,例如

./connect4 9x9 5
将创建一个大小为 9 x 9 并且获胜长度为 5 的棋盘。这是一个简短的示例我是怎么写的:

program Connect4;
uses SysUtils,crt;
const
  Rows = 6;
  Columns = 7;
  Symbols: array[0..2] of char = ('.', '1', '2');
  boardHead: array[0..25] of char = ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z');

type
  TBoard = array of array of integer;

var
  Board: TBoard;
  CurrentPlayer: integer;
  WinSize: integer;

procedure PlayGame;
var
  input: char;
  column, row, turn, g: integer;
  gameOver: boolean;
  {for customize board}
  param, rowsStr, colsStr: string;
  xPos, rows, cols: integer;
begin
{experiment customize board}
if ParamCount > 1 then
begin
  param := ParamStr(1);

  // find the position of the 'x' character in the parameter
  xPos := Pos('x', param);

  // extract the substrings before and after the 'x' character
  rowsStr := Copy(param, 1, xPos - 1);
  colsStr := Copy(param, xPos + 1, Length(param) - xPos);

  // convert the substrings to integers
  Val(rowsStr, rows, xPos);
  Val(colsStr, cols, xPos);

  WinSize :=  StrToInt(ParamStr(2)); 
  SetLength(Board,rows);

  for g := 0 to rows-1 do
    SetLength(Board[g], cols);
  
end
else
begin
  SetLength(Board, Rows);
  for g := 0 to rows-1 do
    SetLength(Board[g], cols);
  WinSize := 4;
  
end;

使用 FreePascal 编译器,它首先编译,但是当我运行 default 时它只显示:

A B C D E F G 
An unhandled exception occurred at $00000001006F3C80:
                                                     EAccessViolation: Access violation
                                                                                         $00000001006F3C80
                                                                                                            $00000001006F47A0

有谁知道导致这个错误的原因吗?

我试图将内存分配分成

setlegth(Board, row)
setlegth(Board[i], columns)
但是它仍然有同样的错误。

有没有我遗漏的东西,或者代码在 Mac 上的工作方式可能不同?

pascal freepascal
1个回答
0
投票

PlayGame()
有一个局部变量
rows
shadows 全局常量
Rows
.

在默认情况下,local

rows
cols
变量未被赋值,但仍在
SetLength()
中使用。您打算改用全局
Rows
Columns

我建议将

SetLength()
调用完全移出
if..else
块,并使用全局常量来初始化局部变量,例如

program Connect4;

uses
  SysUtils, crt;

const
  cRows = 6;
  cColumns = 7;
  cWinSize = 4;
  ...

type
  TBoard = array of array of integer;

var
  Board: TBoard;
  ...
  WinSize: integer;

procedure PlayGame;
var
  ..., g: integer;
  ...
  param, rowsStr, colsStr: string;
  xPos, rows, cols: integer;
begin
  {experiment customize board}
  if ParamCount > 1 then
  begin
    param := ParamStr(1);

    // find the position of the 'x' character in the parameter
    xPos := Pos('x', param);

    // extract the substrings before and after the 'x' character
    rowsStr := Copy(param, 1, xPos - 1);
    colsStr := Copy(param, xPos + 1, MaxInt);

    // convert the substrings to integers
    rows := StrToInt(rowsStr);
    cols := StrToInt(colsStr);

    WinSize := StrToInt(ParamStr(2));
  end else
  begin
    rows := cRows;
    cols := cColumns;
    WinSize := cWinSize;
  end;

  SetLength(Board, rows);
  for g := 0 to rows-1 do
    SetLength(Board[g], cols);
  
  ...
  
end;
© www.soinside.com 2019 - 2024. All rights reserved.