ВЫделение памяти
От: Zip Россия none
Дата: 21.11.07 10:15
Оценка:
Здравствуйте.
В ниже предлагаемом листинге, кроется некая ужасная ошибка. Создаётся двумерный массив указателей. При необходимости выделяется память для структуры в которой содержится динамический массив. До этого момента всё проходит вроде бы успешно. Но при попытке определения количества элементов этого динамического массива появляется ошибка 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;
Re: ВЫделение памяти
От: Dimonka Верблюд  
Дата: 21.11.07 11:04
Оценка:
Здравствуйте, Zip, Вы писали:

Zip>Здравствуйте.

Zip>В ниже предлагаемом листинге, кроется некая ужасная ошибка. Создаётся двумерный массив указателей. При необходимости выделяется память для структуры в которой содержится динамический массив. До этого момента всё проходит вроде бы успешно. Но при попытке определения количества элементов этого динамического массива появляется ошибка access violation.

Почитай о динамических массивах, как у них выделяется память итд.
А ещё лучше почитай сразу про классы , как ими пользоваться, создавать, уничтожать и особенно для начала про TList.
Re[2]: ВЫделение памяти
От: Zip Россия none
Дата: 21.11.07 13:55
Оценка:
Здравствуйте, Dimonka, Вы писали:

D>Почитай о динамических массивах, как у них выделяется память итд.

D>А ещё лучше почитай сразу про классы , как ими пользоваться, создавать, уничтожать и особенно для начала про TList.

Прошу заметить, что чисто логически здесь всё правильно. Скорее всего я имею дело с каким то ограничением компилятора. И если обратить внимание, то можно заметить, что в данном коде я не использую объекты унаследованные от TList, а использую собственные структуры.
Re: ВЫделение памяти
От: Zip Россия none
Дата: 21.11.07 14:37
Оценка:
Оказывается нехватало памяти.


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(Floor,100,200);
 P:=Point(10,20);
 GetMem(Floor[P.x,P.y],SizeOf(Floor[P.x,P.y]^));  //SizeOf(Floor[P.x,P.y]^=8. 
                                                  //Если написать GetMem(Floor[P.x,P.y],8), то
                                                  //всё работает. Почему так?
 SetLength(Floor[P.x,P.y].Descript,1);}
end;


От чего эта проблема?
Re[2]: ВЫделение памяти
От: wallaby  
Дата: 21.11.07 15:26
Оценка: 3 (1)
Здравствуйте, Zip, Вы писали:

Zip>
Zip>begin
Zip> GetMem(Floor,100,200);
Zip> P:=Point(10,20);
Zip> GetMem(Floor[P.x,P.y],SizeOf(Floor[P.x,P.y]^));  //SizeOf(Floor[P.x,P.y]^=8. 
Zip>                                                  //Если написать GetMem(Floor[P.x,P.y],8), то
Zip>                                                  //всё работает. Почему так?
Zip> SetLength(Floor[P.x,P.y].Descript,1);}
Zip>end;
Zip>


Zip>От чего эта проблема?


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
Re[3]: ВЫделение памяти
От: Zip Россия none
Дата: 21.11.07 22:57
Оценка:
Здравствуйте, 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:



Благодарю. Век живи — век учись
Re[4]: ВЫделение памяти
От: Dimonka Верблюд  
Дата: 22.11.07 09:14
Оценка:
Здравствуйте, Zip, Вы писали:

Zip>Благодарю. Век живи — век учись


А я вот считаю, такому учится не нужно. Потом в таких программах чёрт ногу сломит.
Re[5]: ВЫделение памяти
От: wallaby  
Дата: 22.11.07 11:38
Оценка:
Здравствуйте, 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
Re[6]: ВЫделение памяти
От: Dimonka Верблюд  
Дата: 22.11.07 11:57
Оценка: :)
Здравствуйте, wallaby, Вы писали:


W>Не согласен. Иногда динамические массивы очень удобны. К тому исходный пример приводился для поиска ошибки, а не обсуждения архитектуры.

Я не против динамических массивов, я против их такого использования. В каком месте справки написано, что их надо создавать через New?

W>Кстати описанная проблема в равной степени относится к длинным строкам — их тоже надо инициализировать. Если строка — поле записи, и память под эту запись выделять через GetMem — ждите AV при первом обращении к этой строке. В отличие от GetMem процедура New всегда выполняет инициализацию нужных полей (а Dispose — их финализацию, что требуется чтобы не было утечки памяти). И похоже не все это знают.

На практике New совершенно не нужна, каких магических действий бы New не совершала.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.