Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.08.20;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.5 MB
Время: 0.05 c
4-1146219048
Creative
2006-04-28 14:10
2006.08.20
как избавиться от мерцания?


15-1153387859
Nic
2006-07-20 13:30
2006.08.20
Органайзеры, планировщики


2-1154501900
Arsenija
2006-08-02 10:58
2006.08.20
обработка по нажатии ENTER в LabeledEdit


4-1145516275
Dimich1978
2006-04-20 10:57
2006.08.20
Программно нажать на кнопку закрытия формы(крестик)


2-1154507733
Id
2006-08-02 12:35
2006.08.20
Word and Delphi





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский