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[6]: ВЫделение памяти
От: Dimonka Верблюд  
Дата: 22.11.07 11:57
Оценка: :)
Здравствуйте, wallaby, Вы писали:


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

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

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

На практике New совершенно не нужна, каких магических действий бы New не совершала.
ВЫделение памяти
От: 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[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
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.