Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.10.22;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.034 c
15-1159362327
Konstantin555
2006-09-27 17:05
2006.10.22
Проблема с записью 2-х сторонних DVD-дисков


2-1160069377
vain
2006-10-05 21:29
2006.10.22
756E697420556E69


15-1159418753
Climber
2006-09-28 08:45
2006.10.22
sql-запросы


2-1160140411
Xtreme
2006-10-06 17:13
2006.10.22
Delphi.Begin3


2-1160375502
Darkwing
2006-10-09 10:31
2006.10.22
ExtractAssociatedIcon дает пустую иконку.