есть тип Code: type PMem = ^TMem; TMem = record Addr:Pointer; Size:longword; end; в процедуре читаю файл в TMemoryStream. PHP: procedure (var mymem: Tmem); var stmem: TMemoryStream; begin stmem := TMemoryStream.Create; stmem.LoadFromFile('xxxxxx'); mymem.addr := stmem.memory; mymem.size := stmem.size; stmem.free; end; так вот если выполнять stmem.free то после этого естественно память высвобождаеся и я не могу работать с этой областью по средством mymem.addr mymem.size которые вернулись, а если не выполнять то не будет ли это утечкой. Собственно, как высвободить поток при том, что я мог бы потом работать с загруженным в память файлом по средством указателя и размера данных.
Не использовать TMemoryStream а для загрузки/сохранения структуры объявлять типизированный файл, что-то вроде: и процедуры Assign, Writeln, Readln, Eof и т.д.
тогда для этого типа придется делать обвязку ибо поток намного проще шифровать и дешифровать. Можно конечно перейти и к блочному шифрованию при считывании, и разжатие/сжатие, а также вырезка части данных из типа когда надо вырезать чисто data данные а хидер файла не читать. Слишком геморно, проще копировать область данных перед высвобождением и перемещать, но это тоже не есть гуд когда у нас 30 метров данных в оперативе непонятно зачем скопировали а потом удалили. да и mem_file: file of TMem; по сколько бит мы читать то будем)) там надо еще динамический массив под данные, собственно идет memGet и в итоге мы получаем если через ООП тот же поток)
сделай TMem классом, Free будешь вызывать для него таким образом решится проблема утечки, и копировать данные не придется Насчет якобы ухудшения производительности из-за использования классов даже не думай, тесты показывают ухудшение всего лишь на 20-30% по сравнению с записями еще можно TMemoryStream поменять на TFileStream а процедуру оформить в виде функции возвращающей TMem в случае успешной загрузки и nil в случае ошибки.
вообще то TFileStream тоже нужно высвобождать и после его высвобождения будет такая же проблема. TMem классом? зачем? Для данных достаточна указателя и размера в памяти, высвободить их я могу и при помощи MemFree(); Трабла в локальности объекта. т.е. по идее мне нужно залочить изменение переменной в памяти а саму занулить. А создание класса и обработка его дает нам тот же Мемори стрим. проще уж тогда не высвобождать поток совсем а при надобности чистить память через MemFree(); по данным TMem, наверное так и поступлю, в общем то не велика утечка под класс зато нет потери в скорости, а скорость критична.
а если мапить файл или не вариант? что-то типа вот такого: Code: type PMem = ^TMem; TMem = record Addr: Pointer; Size: longword; hFileMap: THandle; end; procedure Mapping(var mymem: Tmem); var hFileMap, hFile: THandle; Mem: Pointer; FileSize: DWORD; begin hFile:= CreateFileA(PChar('file'), GENERIC_WRITE or GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if hFile <> INVALID_HANDLE_VALUE then begin FileSize:= GetFileSize(hFile, nil); hFileMap:= CreateFileMappingA(hFile, nil, PAGE_READWRITE , 0, FileSize, nil); if hFileMap <> INVALID_HANDLE_VALUE then begin CloseHandle(hFile); Mem:= MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, FileSize); if Mem <> nil then begin mymem.size:= FileSize; mymem.addr:= Mem; mymem.hFileMap:= hFileMap; end; end; end; end; procedure FreeTMem(mymem: Tmem); begin UnmapViewOfFile(mymem.addr); CloseHandle(mymem.hFileMap); end; хотя может я что-то не так понял...
а чем по идеологии Stream.Free от UnmapViewOfFile отличается?))) нет не вариант. В общем то решил оставить пока как есть и черт с ним... еще раз говорю очистку можно сделать и через FreeMem а шифровать/дешифровать и жать данные в потоке удобнее, так что это как бы изобретение колеса)
Ты присваиваешь указатель на память другой переменной, поэтому делать stmem.free не стоит (иначе смысл передавать указатель на память?). Вместо этого, по завершению работы с mymem делай команду FreeAndNil(mymem).