Форум: "Начинающим";
Текущий архив: 2006.10.22;
Скачать: [xml.tar.bz2];
ВнизFlat Memory as Dynamic array Найти похожие ветки
← →
andrey44 (2006-10-06 15:06) [0]Общеизвестно, что 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.
← →
Сергей М. © (2006-10-06 15:09) [1]
> A := P;
Здесь радикальная ошибка
← →
Palladin © (2006-10-06 15:20) [2]a:=@p[0]
← →
Palladin © (2006-10-06 15:22) [3]во блин... не посмотрел и написал...
← →
MBo © (2006-10-06 15:32) [4]Цель какая?
← →
Loginov Dmitry © (2006-10-06 16:18) [5]andrey44 (06.10.06 15:06)
Это необходимо для того, что обращаться к участку памяти как к динамическому массиву
А это как это?
← →
Andrey44 (2006-10-06 16:32) [6]> Цель какая?
Цель более высокого уровня - получение быстрого произвольного доступа к двухгиговому memory-mapped файлу.
← →
Palladin © (2006-10-06 16:35) [7]используй PByte или по старинке
TByteArray=Array [0..0] of Byte;
PByteArray=^TByteArray
← →
Сергей М. © (2006-10-06 16:38) [8]
> Andrey44 (06.10.06 16:32) [6]
> двухгиговому
Хоть полны штаны наделаешь, а 2Гб разместить в ВАП ХР-процесса ты не умудришься.
Так что не надо "бабушку лохматить" (с)
← →
Andrey44 (2006-10-06 16:47) [9]> используй PByte или по старинке
Спасибо за совет, это обходное решение у меня давно используется, однако у меня в проекте есть модули с унифицированными интерфейсами, методы которых принимают на вход именно open array и не хотелось бы гонять гигабайты из памяти в память только для преобразования типов. :)
← →
Andrey44 (2006-10-06 16:50) [10]> 2Гб разместить в ВАП ХР-процесса ты не умудришься
Хорошо, пусть будет полтора, пусть будет даже 1, но не меньше. :)
← →
Andrey44 (2006-10-06 16:56) [11]> вход именно open array и не хотелось
Тьфу, оговорился, не open, а dynamic array.
← →
Сергей М. © (2006-10-06 16:59) [12]
> Andrey44 (06.10.06 16:56) [11]
Динамическими массивами как типами данных с управляемым временем жизни "заведует" Делфи-компилятор в неявном взаимодействии с BMM. К MMF это не имеет отношения.
← →
Andrey44 (2006-10-06 17:08) [13]> К MMF это не имеет отношения
Конечно, не имеет, поэтому все это было опущено в исходной постановке задачи. Есть pointer в адресном пространстве процесса. Указывает ли он на MMF или обычную память (которая суть тоже MMF с именем pagefile.dat) знает только операционка. Нужно обратиться к динамическому массиву, который расположен по этому указателю.
← →
sergey L. (2006-10-06 17:17) [14]> Хоть полны штаны наделаешь, а 2Гб разместить в ВАП ХР-процесса ты не умудришься.
Про ключик /3GB в boot.ini не подозреваем? :)
← →
Игорь Шевченко © (2006-10-06 17:23) [15]sergey L. (06.10.06 17:17) [14]
А Delphi уже научилась делать EXEшники, поддерживающие ключик /3Gb ? :)
С флажком IMAGE_FILE_LARGE_ADDRESS_AWARE ? :)
← →
Sapersky (2006-10-06 17:29) [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.
← →
Sergey L. (2006-10-06 18:19) [17]>А Delphi уже научилась делать EXEшники, поддерживающие ключик /3Gb ? :) С флажком IMAGE_FILE_LARGE_ADDRESS_AWARE ? :)
Да, еще в предыдущей версии. Читаем FM по ключевым словам
{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}
← →
Andrey44 (2006-10-06 18:26) [18]> Это чтение по адресу P - 4
Спасибо, самая ценная инфа в топике. :) Выделю в начале участка памяти 4 байта для хранения длины.
← →
MBo © (2006-10-06 18:28) [19]>Выделю в начале участка памяти 4 байта для хранения длины
А что произойдет при SetLength, которым ты почему-то хочешь пользоваться?
← →
Ketmar © (2006-10-06 18:29) [20]>[19] MBo(c) 6-Oct-2006, 18:28
>А что произойдет при SetLength
наверное, что-то очень весёлое. типа AV. %-)
← →
TUser © (2006-10-06 18:34) [21]absolute
хотя непонятно зачем
← →
guav © (2006-10-06 18:43) [22]> [18] Andrey44 (06.10.06 18:26)
Если сам выделяешь, то кто мешает использовать обычный дин. массив и SetLength для выделения ?
Дин массив, кроме P - 4 содержит ещё нечто более интересное по другому смещению, потому следовать совету [16] не советую.
← →
Ketmar © (2006-10-06 18:48) [23]>[22] guav(c) 6-Oct-2006, 18:43
>интересное по другому смещению, потому следовать совету [16] не советую.
или можно, наконец, побороть лень и почитать генофонд на предмет формата динамических массивов и того, как delphi с ними работает. %-)
← →
Andrey44 (2006-10-06 19:32) [24]>интересное по другому смещению, потому следовать совету [16] не >советую.
>или можно, наконец, побороть лень и почитать генофонд на предмет >формата динамических массивов и того, как delphi с ними работает. %-)
Я с удовольствием почитаю, если ткнете, где :) SetLength действительно вызывает AV, но мне это не требуется, нужно только читать. А выделяю я память не сам, я ее только отображаю файл на нее.
← →
Sapersky (2006-10-06 19:47) [25]Help\Object Pascal (или Delphi Language) Reference\Memory Management\Dynamic array types
← →
guav © (2006-10-06 19:47) [26]> Я с удовольствием почитаю, если ткнете, где :)
system.pas
> SetLength действительно вызывает AV, но мне это не требуется,
> нужно только читать
Чтение тоже может приводить к записи в ту область памяти или даже к исключениям.
← →
Ketmar © (2006-10-06 19:48) [27]>[24] Andrey44 6-Oct-2006, 19:32
>Я с удовольствием почитаю, если ткнете, где :)
в генофонде, как я и сказал. там вообще много интересного.
← →
Sapersky (2006-10-06 20:48) [28]Чтение тоже может приводить к записи в ту область памяти
Что-то не могу себе такого представить.
Счётчик ссылок должен меняться при присвоении без приведения типов (вроде A := P), Finalize, SetLength наверное; ещё при передаче массива в качестве параметра функции по значению (без const).
Но чтение, в смысле, доступ к элементам компилятор делает практически так же, как и для массива-указателя ([7]), безо всякого compiler magic. Для одномерных массивов, во всяком случае.
← →
guav © (2006-10-06 21:16) [29]> Счётчик ссылок должен меняться при присвоении без приведения типов
> ещё при передаче массива в качестве параметра функции по значению
> (без const).
Ну да. А ещё - когда переменная покидает область видимости.
Можно конечно занятся эквилибристикой и писать код в котором следя за тем, чтобы ничего из этого не было.
Кстати, читал, что разные версии RTL хранят разное количество информации по отрицательным смещениям (в одних кроме счёта ссылок и длины есть размер выделеннй памяти, в других - нет).
← →
Eraser © (2006-10-06 21:57) [30]> [27] Ketmar © (06.10.06 19:48)
только от версии к версии генофонд меняется...
> [0] andrey44 (06.10.06 15:06)
лучше не изобретать велосипеды, потом проблем будет куча и в конце концов все равно все прийдется переписывать... хотя бы при переходе на 64 разрядную систему и тем более .net.
← →
Ketmar © (2006-10-06 23:21) [31]>[30] Eraser(c) 6-Oct-2006, 21:57
>только от версии к версии генофонд меняется...
поэтому надо затачивать под каждую. %-)
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.10.22;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.044 c