![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Работа с указателями [D6, WinXP]
SkyRanger © (2006-06-30 01:35:00)Подскажите нужно ли явно чистить память. Есть нормально работающий код:
Это чтобы не было вопросов что откуда берется:
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 мега удалось уменьшить занимаемую ядром память. Теперь вот думаю может тут собака порылась? :)
SkyRanger (2006-07-04 05:02:00) [1]Нашел утечку :)
Не пойму правда почему. Судя по Питоновскому хелпу все делаю правильно :(
//====================================================================
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;
Германн (2006-07-04 02:18:00) [2]
> Это не аргумент, а констатация факта :)
Это не констатация факта. Это "отмазка"! (В лучшем случае).
SkyRanger (2006-07-04 00:57:00) [3]Это не аргумент, а констатация факта :)
Игорь Шевченко (2006-07-03 15:15:00) [4]
> Просто код не мой я сразу сказал
Кого-то из отвечающих ? Если нет, то почему ты это приводишь, как аргумент ?
SkyRanger (2006-07-03 09:57:00) [5]Хммм...
Я гляну.. Просто код не мой я сразу сказал :)
evvcom (2006-07-03 09:16:00) [6]Индекс ты считаешь с нуля правильно, но переменные 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".
ЮЮ (2006-07-03 07:36:00) [7]
> Если снять комментарий, то появляется обшибка Access violation.
> Не пойму почему :( Если закоментировать то все ок.
Да уж, AV на сравнении 2х integer. В принципе возможно, если исользовать конструкцию TPyMethods.AddMethod, но чтобы при этом работали остальные строки метода ???
SkyRanger (2006-07-03 04:21:00) [8]> [6] Юрий Зотов © (03.07.06 02:12)
Хмм... Это идея надо будет покопаться :)
SkyRanger (2006-07-03 04:19:00) [9]Вот класс, он основан на коде от 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;
Юрий Зотов (2006-07-03 02:12:00) [10]> а в деструкторе освобождается...
Это в деструкторе НАПИСАНО, что она освобождается. А РЕАЛЬНО она будет освобождаться только если этот деструктор действительно вызывается.
А если нет?
:о)
Например, в объявлении деструктора пропущено override. Или просто где-то банально не уничтожается уже ненужный объект.
Джо (2006-07-03 01:28:00) [11]> [4] SkyRanger © (03.07.06 01:01)
> Насчет Memcheck - он мне находит утечек 62 штуки, при этом
> там, где на мой взгляд все ок. Т.е. память в конструкторе
> выделяется, а в деструкторе освобождается...
> Он всегда точно показывает или как получится???
У меня ни разу ложных срабатываний не наблюдалось...
SkyRanger (2006-07-03 01:01:00) [12]Насчет Memcheck - он мне находит утечек 62 штуки, при этом там, где на мой взгляд все ок. Т.е. память в конструкторе выделяется, а в деструкторе освобождается...
Он всегда точно показывает или как получится???
Джо (2006-06-30 03:09:00) [13]Погоняй с MemCheck ( http://v.mahon.free.fr/pro/freeware/memcheck) или FastMM ( http://fastmm.sourceforge.net). Рекоммендую для отладки первый.
SkyRanger (2006-06-30 02:59:00) [14]Хммм... Спасибо. Тоды буду копаться дальше. Должна же где то не освобождаться память. И скорее косяк с указателем раз стабильно утечка по 4 или 8 байт. Ну по восемь не обязательно. Может быть просто очень быстро по 4, просто винда не показывает... :(
Германн (2006-06-30 01:41:00) [15]
> А надо ли что нить делать с CurrWin в самом конце функции.
Нет. Это просто локальная переменная размером в 4 байта, которой при входе в метод было "выделено" пространство в стеке, а при выходе "изъято".