Ваши проблемы начинаются здесь:
Move(matA, matB, Sizeof(matA[0]) * Length(matA));
Вы передаете динамический массив c в Move
. Динамический массив c реализован как указатель на первый элемент массива. Поэтому вы перезаписываете указатель.
Возможно, вы хотели сделать что-то вроде этого:
Move(matA[0], matB[0], Sizeof(matA[0]) * Length(matA));
Но вы тоже не хотите этого делать. Это использует Move
для управляемого типа, что является точно такой же ошибкой, которую вы допустили в в своем предыдущем вопросе .
Фактически, если вы просто удалите эту строку кода, она должна работать. Обратите внимание, что я не проверил подробно, поэтому могут быть другие дефекты.
Ваш код действительно очень сложный, и очень трудно увидеть, что происходит. По крайней мере, некоторые из ваших проблем связаны с тем, что ваш код так запутан. Постарайтесь не помещать огромное количество кода в одну процедуру. Разделите код на более мелкие части, а затем склейте эти меньшие части вместе в подпрограмме драйвера.
Вы хотите использовать функцию, подобную этой:
function CloneMatrixInt(const matrix: array of ArrayInt): MatrixInt;
var
i: Integer;
begin
SetLength(Result, Length(matrix));
for i := 0 to High(Result) do
Result[i] := Copy(matrix[i]);
end;
Обратите внимание, что это по существу идентично на ответ на ваш предыдущий вопрос. Почему это так?
Вам нужно перестать думать о MatrixInt
как о многомерном массиве. Это не. Это просто массив. Это массив, элементы которого, в свою очередь, также являются массивами. Технически это зазубренный массив. Но вам просто нужно думать о нем как об одномерном массиве.
Таким образом, функция для его клонирования работает следующим образом:
- Выделите целевой массив.
- L oop над массивом назначения, клонирующим каждый элемент из исходного массива.
Это точно такой же процесс, как и в предыдущем вопросе. Там у нас был массив записей с функцией клонирования этой записи. Но поскольку мы отделили две задачи клонирования внешнего массива от клонирования элементов массива, полученный код по существу идентичен.
Теперь представьте, что у вас есть массив MatrixInt
. Допустим,
type
ArrayMatrixInt = array of MatrixInt;
Хорошо, клонируйте это так:
function CloneArrayMatrixInt(const arrayMatrix: array of MatrixInt): ArrayMatrixInt;
var
i: Integer;
begin
SetLength(Result, Length(arrayMatrix));
for i := 0 to High(Result) do
Result[i] := CloneMatrixInt(matrix[i]);
end;
Угадайте что, тот же самый код, что и раньше!
Учитывая этот вопрос, и ваш предыдущий Во-первых, могу ли я предложить вам отказаться от использования Move
для решения всех проблем. Нет никаких оснований полагать, что любая из проблем, с которыми вы сталкиваетесь, будет решена с помощью Move
.
Одна последняя заметка. Неровные массивы выделяются дорого, потому что они требуют многократного выделения. С ними также неэффективно работать, потому что они не хранятся непрерывно. Delphi не хватает типа многомерного массива, и, если требуется максимальная производительность, вам лучше всего реализовать тип многомерного массива.