Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Ошибка при освобождении памяти


Автор: Lonley 6.11.2007, 18:34
ПРИВЕТ ВСЕМ.....
У меня в буфере находится некая информация
причем строчного формата т.е. для вывода на экран smile 
не типа String
-----------------------------
далее узнается размер инициализируется массив на данный размер
далле выделяется память VirtualAlloc и формируются строки типа Stringв ручную
-----------------------------
прописывается адресс строки в массиве И.....
-----------------------------
все какбы прекрасно строки выводятся все хорошо, но при
выходе из функции динамич массив освобождается тут и начинается
проблема 
-----------------------------
МНЕ конечно понятно что в строках (массива) указаны адреса на мою выделенную память,
но собственно какая разница память и память

-----------------------------
Код

.................
.................
.................
   SetLength(Result.aLP,c); //инициализация массива
   i  := 0;
   ii := 0;
{еужно посчитать весь размер подстроки 4 байта под хранения рамера + сама строка
т.е. 4 + [0] }
  lenbuff := 4 * cfild * c;
  asm
   mov esi,addr
   add esi,$0b
  end;
while i <> c do           //------------begin while RECORD
  begin
   while ii <> cfild do
    begin                 //------------begin while FIELDS
     asm
       xor ebx,ebx            //
       mov bl,byte ptr[esi];  //
       add lenbuff,bx         //
       add esi,ebx            //
       add esi,2              //
     end;
      inc (ii);
    end;                  //------END WHILE FIELDS
    ii := 0;
    inc(i);
  end;                    //------END WHILE RECORD
//------------------------------------------------------------------------------
  asm
   push  PAGE_READWRITE   //тип доступа
   push  MEM_COMMIT       //способ получения
   movzx eax,lenbuff      //
   push  eax              //его размер
   push  0                //указатель на базовый адрес
   call  VirtualAlloc     //
   
   cmp   eax,0            //
   je    _error           //
   mov buffstring,eax     //адресс буфера
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    mov   esi,addr            //
    add   esi,$0b             //
    mov   edi,buffstring      //
    movzx ecx,byte ptr [esi]  //
    mov   [edi],ecx
    add   esi,1               //
    add   edi,4               //
rep movsb                     //пересылаем саму строку
  end;
   Result.aLP[0].Name := '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@';
   d := @Result.aLP[0].Name;
  asm
   mov edi,buffstring
   mov esi,d
   add edi,4
   mov [esi],edi
 end;
//------------------------------------------------------------------------------
 MessageBoxA (HandleProcess,PAnsiChar(Result.aLP[0].Name),'HELLO',0);
_error:
 MessageBoxA (HandleProcess,'выделить память под строки не удалось','error',0);
_ok:
// TODO 2 -oILYA -cВпроцед : ПОлучаем данные из файла дописать
 asm
   push MEM_DECOMMIT
   push 0
   mov  eax,buffstring
   push eax
   call VirtualFree
 end;
 end;

Автор: bems 6.11.2007, 19:28
у строки кроме самой строки и 4-х байт длины есть еще 4 байта счетчика ссылок и завершающий ноль (для совместимости с PChar). Я в асме не силен, поэтому не могу найти у тебя ошибку. Но вместо ручного создания string ты лучше объяви ее, сделай ей SetLength и скопируй в нее содержимое буффера. И VirtualAlloc не понадобится

Автор: Lonley 7.11.2007, 09:24
bems, 
-----
спасибо будем думать дальше  smile 

Автор: Rouse_ 7.11.2007, 21:55
Ты забыл вызов _LStrClr

Автор: Lonley 8.11.2007, 11:54
Rouse_, 
поясни... в отладчике она есть я видел....судя по Аббревиатуре очищает строку smile 

Автор: Lonley 9.11.2007, 20:33
все разобрался.... если правильно сформировать строку то память освобождается без ошибок
------------
Код

OFFSET - 8 | OFFSET - 4 | OFFSET -0     |OFFSET + (OFFSET-4)|
------------------------------------------------------------
 FFFF FFFF  | размер      | начала стро | завершающий ноль с выравниванием |
------------------------------------------------------------

-------------------------------------
соответственно освбождать память самому не нужно т.к. при выходе из функции
программа попытаеться сама освободить память что вызовет ошибку
-------------------------------------
bems,   +1

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)