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

Вниз

Работа с указателями   Найти похожие ветки 

 
SkyRanger ©   (2006-06-30 01:35) [0]

Подскажите нужно ли явно чистить память. Есть нормально работающий код:

Это чтобы не было вопросов что откуда берется:


TGLCollection = array [0..ENGINE_MAX_POINTERS] of Pointer;

TGLManager = class
protected
 FCollection       : TGLCollection;
 FPython           : TPython;
 FCount            : Integer;
 FIsActiveControls : Boolean;

 public
   procedure Add(); virtual; abstract;
   property Count : Integer read FCount write FCount;
end;

TGLWindowsManager = class (TGLManager)
...
end;

function TGLWindowsManager.Add(WinSkinPrefix:String;
var
CurrWin  : TGLWindow;
WRec  : TGLWindowRec;
begin

FCollection[FCount]:=TGLWindow.Create(WinSkinPrefix,
                  BorderWidth,BorderHeight,HeaderHeight,
TGLWindow(FCollection[FCount]).WindowName:=WinName;
TGLWindow(FCollection[FCount]).WinIndex:=FCount;
TGLWindow(FCollection[FCount]).WindowType:=GL_NORMAL_WINDOW;
Result:=FCount;

Inc(FCount);

end;


И собственно код:


procedure TGLWindowsManager.DrawById(WinId:Integer);
var
 I:Integer;
 CurrWin : TGLWindow;
begin
 for I:=0 to FCount-1 do
 begin
   CurrWin:=TGLWindow(FCollection[I]);
   if CurrWin.WinIndex=WinID then
     if CurrWin.Visible=1 then
       begin
         TGLWindow(FCollection[I]).Draw;
         if Trim(CurrWin.pyFuncName)<>"" then
           FPython.CallFuncByName(PChar(CurrWin.pyFuncName),nil);
       exit;
     end;
 end;
end;


Вопрос такой:
А надо ли что нить делать с CurrWin в самом конце функции. Т.е. возможна ли тут утечка памяти.
Просто пытаюсь найти откуда у меня в сукунду 4 или 8 байт утечка памяти. Сначала думал на Питон, но вроде разобрался с ним и на 4 мега удалось уменьшить занимаемую ядром память. Теперь вот думаю может тут собака порылась? :)


 
Германн ©   (2006-06-30 01:41) [1]


> А надо ли что нить делать с CurrWin в самом конце функции.

Нет. Это просто локальная переменная размером в 4 байта, которой при входе в метод было "выделено" пространство в стеке, а при выходе "изъято".


 
SkyRanger ©   (2006-06-30 02:59) [2]

Хммм... Спасибо. Тоды буду копаться дальше. Должна же где то не освобождаться память. И скорее косяк с указателем раз стабильно утечка по 4 или 8 байт. Ну по восемь не обязательно. Может быть просто очень быстро по 4, просто винда не показывает... :(


 
Джо ©   (2006-06-30 03:09) [3]

Погоняй с MemCheck (http://v.mahon.free.fr/pro/freeware/memcheck) или FastMM (http://fastmm.sourceforge.net). Рекоммендую для отладки первый.


 
SkyRanger ©   (2006-07-03 01:01) [4]

Насчет Memcheck - он мне находит утечек 62 штуки, при этом там, где на мой взгляд все ок. Т.е. память в конструкторе выделяется, а в деструкторе освобождается...
Он всегда точно показывает или как получится???


 
Джо ©   (2006-07-03 01:28) [5]

> [4] SkyRanger ©   (03.07.06 01:01)
> Насчет Memcheck - он мне находит утечек 62 штуки, при этом
> там, где на мой взгляд все ок. Т.е. память в конструкторе
> выделяется, а в деструкторе освобождается...
> Он всегда точно показывает или как получится???

У меня ни разу ложных срабатываний не наблюдалось...


 
Юрий Зотов ©   (2006-07-03 02:12) [6]

> а в деструкторе освобождается...

Это в деструкторе НАПИСАНО, что она освобождается. А РЕАЛЬНО она будет освобождаться только если этот деструктор действительно вызывается.

А если нет?
:о)

Например, в объявлении деструктора пропущено override. Или просто где-то банально не уничтожается уже ненужный объект.


 
SkyRanger ©   (2006-07-03 04:19) [7]

Вот класс, он основан на коде от http://mmm-experts.com/
Я оставил только то что нужно, а принцип остался тот же.
Так вот в методе TPyMethods.AddMethod закоментированно условие.
Если снять комментарий, то появляется обшибка Access violation.
Не пойму почему :( Если закоментировать то все ок.

MemCheck ругается на утечку в строке
   ReAllocMem( FMethods, SizeOf(PyMethodDef)*(FAllocatedMethodCount+1));
даже не на утечку, просто сам мемчек дает ошибку у себя в коде...

Вот мне и интересно что тут может быть неправильно :(



 TMethodArray = array[ 0 .. 16000 ] of PyMethodDef;
 PMethodArray = ^TMethodArray;

//--------------------------------------------------------
//--                                                    --
//-- class:  TPyMethods                                 --
//-- Methods to be called inside Python script and      --
//-- Module for import inside Python script             --
//--------------------------------------------------------

 TPyMethods = class
 private
   FMethods              : PPyMethodDef;
   FMethodsCount         : Integer;
 FAllocatedMethodCount : Integer;

 function GetMethod( Index : Integer ) : PPyMethodDef;

 public
   constructor Create;
   destructor Destroy;  override;

   function AddMethod( AMethodName : PChar;
                       AMethod  : PyCFunction;
                       ADocString : PChar ) : PPyMethodDef;
   property Methods : PPyMethodDef read FMethods write FMethods;
   property MethodsIdx[ idx : Integer ] : PPyMethodDef read GetMethod;
 end;

{TPyMethods}

constructor TPyMethods.Create;
begin
   Assert(FMethods = nil);
   FAllocatedMethodCount:=PYT_METHOD_BUFFER_INCREASE;
   FMethodsCount:=0;
   FMethods:=PPyMethodDef(AllocMem(SizeOf(PyMethodDef)*(FAllocatedMethodCount+1)));
   FillChar(FMethods^, Sizeof(FMethods^)*FAllocatedMethodCount, 0);
end;

//--------------------------------------------------------------------

destructor TPyMethods.Destroy;
begin
 if Assigned(FMethods) then
 begin
   FreeMem(FMethods);
   FMethods := nil;
 end;
 FAllocatedMethodCount := 0;
 FMethodsCount := 0;
end;

//--------------------------------------------------------------------

function TPyMethods.GetMethod( Index : Integer ) : PPyMethodDef;
begin
 if (Index < 0) or (Index > FMethodsCount) then
   raise Exception.CreateFmt("%s: Index %d out of range", [ClassName, Index]);
 Result := @( PMethodArray(FMethods)^[Index] );
end;

function TPyMethods.AddMethod( AMethodName : PChar;
                              AMethod  : PyCFunction;
                              ADocString : PChar ) : PPyMethodDef;
var
 MethodPtr : PPyMethodDef;
begin
//  if FMethodsCount = FAllocatedMethodCount then
 begin
   Inc( FAllocatedMethodCount, PYT_METHOD_BUFFER_INCREASE );
   ReAllocMem( FMethods, SizeOf(PyMethodDef)*(FAllocatedMethodCount+1));
   MethodPtr :=@(PMethodArray(FMethods)^[FMethodsCount+1]);
   FillChar( MethodPtr^,SizeOf(PyMethodDef)*PYT_METHOD_BUFFER_INCREASE,0);
 end;
 Result:=MethodsIdx[FMethodsCount];
 Result^.ml_meth:=PyCFunction(AMethod);
 Result^.ml_name:=AMethodName;
 Result^.ml_doc:=ADocString;
 Result^.ml_flags := METH_VARARGS;
 Inc(FMethodsCount);
end;


 
SkyRanger ©   (2006-07-03 04:21) [8]

> [6] Юрий Зотов ©   (03.07.06 02:12)

Хмм... Это идея надо будет покопаться :)


 
ЮЮ ©   (2006-07-03 07:36) [9]


> Если снять комментарий, то появляется обшибка Access violation.
> Не пойму почему :( Если закоментировать то все ок.


Да уж, AV на сравнении 2х integer. В принципе возможно, если исользовать конструкцию TPyMethods.AddMethod, но чтобы при этом работали остальные строки метода ???


 
evvcom ©   (2006-07-03 09:16) [10]

Индекс ты считаешь с нуля правильно, но переменные FMethodsCount, FAllocatedMethodCount используешь нелогично. Судя по их названию - это количество элементов, оно на 1 больше, чем индекс последнего эл-та. Поэтому

>   Inc( FAllocatedMethodCount, PYT_METHOD_BUFFER_INCREASE);
>   ReAllocMem( FMethods, SizeOf(PyMethodDef)*(FAllocatedMethodCount+1)); // нелогично!
> MethodPtr :=@(PMethodArray(FMethods)^[FMethodsCount+1]); // нелогично!
...
> Result:=MethodsIdx[FMethodsCount]; // А здесь логичным было бы FMethodsCount - 1

Явных ошибок вроде не заметил, но путаница с индексами... Ты уж определись, или ты называешь переменные "Count" и используешь их как количество, или так как используешь, но переменные переименовываешь в "LastIndex".


 
SkyRanger ©   (2006-07-03 09:57) [11]

Хммм...
Я гляну.. Просто код не мой я сразу сказал :)


 
Игорь Шевченко ©   (2006-07-03 15:15) [12]


> Просто код не мой я сразу сказал


Кого-то из отвечающих ? Если нет, то почему ты это приводишь, как аргумент ?


 
SkyRanger ©   (2006-07-04 00:57) [13]

Это не аргумент, а констатация факта :)


 
Германн ©   (2006-07-04 02:18) [14]


> Это не аргумент, а констатация факта :)

Это не констатация факта. Это "отмазка"! (В лучшем случае).


 
SkyRanger ©   (2006-07-04 05:02) [15]

Нашел утечку :)
Не пойму правда почему. Судя по Питоновскому хелпу все делаю правильно :(

//====================================================================

procedure pySetDoubleToObject(PyObj : PPyObject; ObjName:PChar; Value:Double;
                             CalledFrom : String);
var
 P:PPyObject;
begin
P:=PyFloat_FromDouble(Value);
 PyObject_SetAttrString(PyObj, ObjName, P);
 PyErrorCheckExt(P, "pySetDoubleToObject: "+ObjName+chr(10)+
                   "Called from: "+CalledFrom);
 Py_XDECREF(P);
end;

//====================================================================

procedure pySetLongToObject(PyObj : PPyObject; ObjName:PChar; Value:Integer;
                             CalledFrom : String);
var
 P:PPyObject;
begin
 P:=PyLong_FromLong(Value);
PyObject_SetAttrString(PyObj, ObjName, P);
 PyErrorCheckExt(P, "pySetLongToObject: "+ObjName+chr(10)+
                   "Called from: "+CalledFrom);
 Py_XDECREF(P);
end;

//====================================================================

procedure pySetStringToObject(PyObj : PPyObject; ObjName:PChar; Value : PChar;
                             CalledFrom : String);
var
 P:PPyObject;
begin
 P:=PyString_FromString(Value);
 PyObject_SetAttrString(PyObj, ObjName, P);
 PyErrorCheckExt(P, "pySetStringToObject: "+ObjName+chr(10)+
                   "Called from: "+CalledFrom);
 Py_XDECREF(P);
end;



Страницы: 1 вся ветка

Текущий архив: 2006.08.20;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.091 c
4-1146397041
zaN0za
2006-04-30 15:37
2006.08.20
Проблема с чтением из файла


5-1137761437
olegz77
2006-01-20 15:50
2006.08.20
Запись/Чтение неопубликованных свойств компонента


2-1154512267
Barnikle
2006-08-02 13:51
2006.08.20
найти слово в тексте


5-1127570241
bneuro
2005-09-24 17:57
2006.08.20
Помещение в DLL своего компонента


2-1154417827
elysee
2006-08-01 11:37
2006.08.20
Запрос