Здравствуйте.
В ниже предлагаемом листинге, кроется некая ужасная ошибка. Создаётся двумерный массив указателей. При необходимости выделяется память для структуры в которой содержится динамический массив. До этого момента всё проходит вроде бы успешно. Но при попытке определения количества элементов этого динамического массива появляется ошибка access violation.
type
TTileDescriptionr=record
Layer:byte;
Tile: word;
Mask: word;
end;
TTileDescription=record
Count: word;
Descript: array of TTileDescriptionr;
end;
PTileDescription = ^TTileDescription;
var
Floor:array of array of PTileDescription;
P:TPoint;
begin
GetMem(Map.Data.Floor,100,200);
P:=Point(10,20);
GetMem(Map.Data.Floor[P.x,P.y],SizeOf(Map.Data.Floor[P.x,P.y]^));
SetLength(Map.Data.Floor[P.x,P.y].Descript,1);}
end;
Здравствуйте, Zip, Вы писали:
Zip>Здравствуйте. Zip>В ниже предлагаемом листинге, кроется некая ужасная ошибка. Создаётся двумерный массив указателей. При необходимости выделяется память для структуры в которой содержится динамический массив. До этого момента всё проходит вроде бы успешно. Но при попытке определения количества элементов этого динамического массива появляется ошибка access violation.
Почитай о динамических массивах, как у них выделяется память итд.
А ещё лучше почитай сразу про классы , как ими пользоваться, создавать, уничтожать и особенно для начала про TList.
Здравствуйте, Dimonka, Вы писали:
D>Почитай о динамических массивах, как у них выделяется память итд. D>А ещё лучше почитай сразу про классы , как ими пользоваться, создавать, уничтожать и особенно для начала про TList.
Прошу заметить, что чисто логически здесь всё правильно. Скорее всего я имею дело с каким то ограничением компилятора. И если обратить внимание, то можно заметить, что в данном коде я не использую объекты унаследованные от TList, а использую собственные структуры.
1) Заменить GetMem(Floor,100,200) на SetLength(Floor,100,200)
2) Динамические массивы необходимо инициализировать, прежде чем с ними можно будет работать, GetMem этого не делает. В данном случае вместо GetMem(Floor[P.x,P.y],SizeOf(Floor[P.x,P.y]^)) нужно New:
begin
SetLength(Floor,100,200);
P:=Point(10,20);
New(Floor[P.x,P.y]); //SizeOf(Floor[P.x,P.y]^=8.
SetLength(Floor[P.x,P.y].Descript,1);
end.
---
The optimist proclaims that we live in the best of all possible worlds; and the pessimist fears this is true
Здравствуйте, wallaby, Вы писали:
W>1) Заменить GetMem(Floor,100,200) на SetLength(Floor,100,200)
W>2) Динамические массивы необходимо инициализировать, прежде чем с ними можно будет работать, GetMem этого не делает. В данном случае вместо GetMem(Floor[P.x,P.y],SizeOf(Floor[P.x,P.y]^)) нужно New:
Здравствуйте, Dimonka, Вы писали:
D>А я вот считаю, такому учится не нужно. Потом в таких программах чёрт ногу сломит.
Не согласен. Иногда динамические массивы очень удобны. К тому исходный пример приводился для поиска ошибки, а не обсуждения архитектуры. Кстати описанная проблема в равной степени относится к длинным строкам — их тоже надо инициализировать. Если строка — поле записи, и память под эту запись выделять через GetMem — ждите AV при первом обращении к этой строке. В отличие от GetMem процедура New всегда выполняет инициализацию нужных полей (а Dispose — их финализацию, что требуется чтобы не было утечки памяти). И похоже не все это знают.
---
The optimist proclaims that we live in the best of all possible worlds; and the pessimist fears this is true
W>Не согласен. Иногда динамические массивы очень удобны. К тому исходный пример приводился для поиска ошибки, а не обсуждения архитектуры.
Я не против динамических массивов, я против их такого использования. В каком месте справки написано, что их надо создавать через New?
W>Кстати описанная проблема в равной степени относится к длинным строкам — их тоже надо инициализировать. Если строка — поле записи, и память под эту запись выделять через GetMem — ждите AV при первом обращении к этой строке. В отличие от GetMem процедура New всегда выполняет инициализацию нужных полей (а Dispose — их финализацию, что требуется чтобы не было утечки памяти). И похоже не все это знают.
На практике New совершенно не нужна, каких магических действий бы New не совершала.