Вопрос, заданный пользователем, касается работы с указателями на двумерные массивы в языке программирования Object Pascal, который используется в среде разработки Delphi. Пример кода, представленный в вопросе, демонстрирует попытку создания указателя на двумерный массив символов, его заполнение символами "#", вывод в консоль и освобождение памяти, выделенной под указатель. При использовании метода Dispose() возникает ошибка выполнения 216. Рассмотрим, почему это происходит, и предложим возможные решения.
Проблема с индексацией массива
Ошибка возникает из-за неправильной индексации двумерного массива. В языке Object Pascal индексация массивов начинается с единицы, а не с нуля. Следовательно, в цикле заполнения массива должен использоваться диапазон от 1 до LinesNum и от 1 до ColumnsNum соответственно.
for i := 1 to LinesNum do
begin
for j := 1 to ColumnsNum do
begin
CurGrid^[i][j] := '#';
end;
end;
Исправление кода
Исправленный код должен выглядеть следующим образом:
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 := 1 to LinesNum do
begin
for j := 1 to ColumnsNum do
begin
CurGrid^[i][j] := '#';
end;
end;
FillGrid := CurGrid;
end;
procedure ShowGrid(CurGrid: GridPtr);
var
i, j: Integer;
begin
for i := 1 to LinesNum do
begin
for j := 1 to ColumnsNum do
begin
Write(CurGrid^[i][j]);
end;
WriteLn; { newline character in ASCII }
end;
end;
var
CurGrid: GridPtr;
begin
New(CurGrid);
CurGrid := FillGrid(CurGrid);
ShowGrid(CurGrid);
Dispose(CurGrid);
end.
Альтернативное решение
В качестве альтернативного подхода можно использовать динамическое массивы, которые автоматически управляют выделением и освобождением памяти:
program GridShowerAlternative;
type
TGrid = array of array of char;
PGrid = ^TGrid;
function CreateGrid(Lines, Columns: Integer): PGrid;
var
GridSize: Integer;
begin
GridSize := SizeOf(TGrid) * (Lines + 1) + SizeOf(char) * Lines * Columns;
Result := GetMem(TGrid(GridSize), Lines + 1, Columns);
SetLength(Result^, Lines, Columns);
for var i := Low(Result^, 1) to High(Result^, 1) do
for var j := Low(Result^[i], 1) to High(Result^[i], 1) do
Result^[i][j] := '#';
end;
procedure ShowGrid(AGrid: PGrid);
var
i, j: Integer;
begin
for i := Low(AGrid^, 1) to High(AGrid^, 1) do
begin
for j := Low(AGrid^[i], 1) to High(AGrid^[i], 1) do
Write(AGrid^[i][j]);
WriteLn;
end;
end;
var
CurGrid: PGrid;
begin
CurGrid := CreateGrid(14, 28);
ShowGrid(CurGrid);
SetLength(CurGrid^, 0, 0); { Освобождаем память }
FreeMem(CurGrid, SizeOf(TGrid) * (High(CurGrid^, 1) + 1));
end.
В этом примере используется тип TGrid для двумерного массива с динамическим управлением размером. Функция CreateGrid выделяет память для массива, а процедура ShowGrid выводит его содержимое. После использования массив освобождается с помощью SetLength и FreeMem.
Заключение
Правильная работа с указателями на двумерные массивы в Object Pascal требует точного соблюдения правил индексации. Использование динамических массивов может упростить управление памятью и избежать ошибок, связанных с некорректным освобождением памяти.
Пользователь спрашивает о работе с указателями на двумерные массивы в Object Pascal, используя среду Delphi, и столкнулся с ошибкой при использовании метода Dispose().
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS