![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Flat Memory as Dynamic array [D5, D6, D7, WinXP]
andrey44 © (2006-10-06 15:06:00)Общеизвестно, что Dynamic Array представляются в Delphi указателем на первый элемент и индексом последнего. Как можно напрямую установить эти значения? Это необходимо для того, что обращаться к участку памяти как к динамическому массиву. Пробовал следующий тривиальный код, к данным обращаться можно, но попытка вызова SetLength приводит к затиранию значений массива.
type
TArray = array of Byte;
var
A: TArray;
P: pointer;
begin
GetMem (P, 10);
FillChar (P^, 10, 100);
A := P;
SetLength (A, 10);
A[0] := 1;
FreeMem (P);
end.
Ketmar (2006-10-06 23:21:00) [1]>[30] Eraser(c) 6-Oct-2006, 21:57
>только от версии к версии генофонд меняется...
поэтому надо затачивать под каждую. %-)
Eraser (2006-10-06 21:57:00) [2]> [27] Ketmar © (06.10.06 19:48)
только от версии к версии генофонд меняется...
> [0] andrey44 (06.10.06 15:06)
лучше не изобретать велосипеды, потом проблем будет куча и в конце концов все равно все прийдется переписывать... хотя бы при переходе на 64 разрядную систему и тем более .net.
guav (2006-10-06 21:16:00) [3]> Счётчик ссылок должен меняться при присвоении без приведения типов
> ещё при передаче массива в качестве параметра функции по значению
> (без const).
Ну да. А ещё - когда переменная покидает область видимости.
Можно конечно занятся эквилибристикой и писать код в котором следя за тем, чтобы ничего из этого не было.
Кстати, читал, что разные версии RTL хранят разное количество информации по отрицательным смещениям (в одних кроме счёта ссылок и длины есть размер выделеннй памяти, в других - нет).
Sapersky (2006-10-06 20:48:00) [4]Чтение тоже может приводить к записи в ту область памяти
Что-то не могу себе такого представить.
Счётчик ссылок должен меняться при присвоении без приведения типов (вроде A := P), Finalize, SetLength наверное; ещё при передаче массива в качестве параметра функции по значению (без const).
Но чтение, в смысле, доступ к элементам компилятор делает практически так же, как и для массива-указателя ([7]), безо всякого compiler magic. Для одномерных массивов, во всяком случае.
Ketmar (2006-10-06 19:48:00) [5]>[24] Andrey44 6-Oct-2006, 19:32
>Я с удовольствием почитаю, если ткнете, где :)
в генофонде, как я и сказал. там вообще много интересного.
guav (2006-10-06 19:47:00) [6]> Я с удовольствием почитаю, если ткнете, где :)
system.pas
> SetLength действительно вызывает AV, но мне это не требуется,
> нужно только читать
Чтение тоже может приводить к записи в ту область памяти или даже к исключениям.
Sapersky (2006-10-06 19:47:00) [7]Help\Object Pascal (или Delphi Language) Reference\Memory Management\Dynamic array types
Andrey44 (2006-10-06 19:32:00) [8]>интересное по другому смещению, потому следовать совету [16] не >советую.
>или можно, наконец, побороть лень и почитать генофонд на предмет >формата динамических массивов и того, как delphi с ними работает. %-)
Я с удовольствием почитаю, если ткнете, где :) SetLength действительно вызывает AV, но мне это не требуется, нужно только читать. А выделяю я память не сам, я ее только отображаю файл на нее.
Ketmar (2006-10-06 18:48:00) [9]>[22] guav(c) 6-Oct-2006, 18:43
>интересное по другому смещению, потому следовать совету [16] не советую.
или можно, наконец, побороть лень и почитать генофонд на предмет формата динамических массивов и того, как delphi с ними работает. %-)
guav (2006-10-06 18:43:00) [10]> [18] Andrey44 (06.10.06 18:26)
Если сам выделяешь, то кто мешает использовать обычный дин. массив и SetLength для выделения ?
Дин массив, кроме P - 4 содержит ещё нечто более интересное по другому смещению, потому следовать совету [16] не советую.
TUser (2006-10-06 18:34:00) [11]absolute
хотя непонятно зачем
Ketmar (2006-10-06 18:29:00) [12]>[19] MBo(c) 6-Oct-2006, 18:28
>А что произойдет при SetLength
наверное, что-то очень весёлое. типа AV. %-)
MBo (2006-10-06 18:28:00) [13]>Выделю в начале участка памяти 4 байта для хранения длины
А что произойдет при SetLength, которым ты почему-то хочешь пользоваться?
Andrey44 (2006-10-06 18:26:00) [14]> Это чтение по адресу P - 4
Спасибо, самая ценная инфа в топике. :) Выделю в начале участка памяти 4 байта для хранения длины.
Sergey L. (2006-10-06 18:19:00) [15]>А Delphi уже научилась делать EXEшники, поддерживающие ключик /3Gb ? :) С флажком IMAGE_FILE_LARGE_ADDRESS_AWARE ? :)
Да, еще в предыдущей версии. Читаем FM по ключевым словам
{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}
Sapersky (2006-10-06 17:29:00) [16]Если очень хочется:
GetMem (P, 10);
FillChar (P^, 10, 100);
Pointer(A) := P;
// Не использовать Length(A) и SetLength!!! Равно как и ReAllocMem(P)
A[0] := 1;
Pointer(A) := nil; // иначе дельфи попытается его освободить самостоятельно
FreeMem(P);
Но лучше всё-таки как в [7]. Потому что Length(A) может вызвать сам Дельфи (когда попытаешься посмотреть содержимое массива при отладке, например). Это чтение по адресу P - 4, т.е. вне выделенного блока - возможно AV.
Игорь Шевченко (2006-10-06 17:23:00) [17]sergey L. (06.10.06 17:17) [14]
А Delphi уже научилась делать EXEшники, поддерживающие ключик /3Gb ? :)
С флажком IMAGE_FILE_LARGE_ADDRESS_AWARE ? :)
sergey L. (2006-10-06 17:17:00) [18]> Хоть полны штаны наделаешь, а 2Гб разместить в ВАП ХР-процесса ты не умудришься.
Про ключик /3GB в boot.ini не подозреваем? :)
Andrey44 (2006-10-06 17:08:00) [19]> К MMF это не имеет отношения
Конечно, не имеет, поэтому все это было опущено в исходной постановке задачи. Есть pointer в адресном пространстве процесса. Указывает ли он на MMF или обычную память (которая суть тоже MMF с именем pagefile.dat) знает только операционка. Нужно обратиться к динамическому массиву, который расположен по этому указателю.
Сергей М. (2006-10-06 16:59:00) [20]
> Andrey44 (06.10.06 16:56) [11]
Динамическими массивами как типами данных с управляемым временем жизни "заведует" Делфи-компилятор в неявном взаимодействии с BMM. К MMF это не имеет отношения.