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

Вниз

Проблема со строками 8-(   Найти похожие ветки 

 
Cobalt ©   (2002-09-16 09:35) [0]

Строки копируются не всегда, а время от времени

Procedure TProcessList.Add_PInfo(AInfo:TProcessEntry32);
var tmp:PProcessInfo;
begin
if First=nil
then
begin
GetMem(First,SizeOf(TProcessInfo));
tmp:=First;
end
else
begin //Находим последний элемент с пустым "окончанием"
tmp:=First;
while tmp.Next<>nil do
tmp:=tmp.Next;
GetMem(tmp.Next,SizeOf(TProcessInfo));
tmp:=tmp.Next;
end;
with tmp^ do
begin
PID:=AInfo.th32ProcessID;
OwnPID:=AInfo.th32ParentProcessID;
Checked:=false;
Next:=nil;
//SetLength(FullName,length(AInfo.szExeFile));
FullName:=Application.ExeName; Здесь происходит AV
// FullName:=AInfo.szExeFile;
except
end
end;
end;
PProcessInfo = ^TProcessInfo;

TProcessInfo = record
PID,
OwnPID : Cardinal;
FullName : string;
Checked : boolean;
Next : PProcessInfo;
end;

TProcessList = class
First : PProcessInfo;
Constructor Create;
Procedure Add_PInfo(AInfo:TProcessEntry32);
Function DuplicateExist(AInfo:PProcessInfo):boolean;
Destructor Destroy;reintroduce;
end;

Может кто подскажет, где можно тут накосячить?


 
REA   (2002-09-16 10:59) [1]

А не из DLL код вызывается?


 
Alx2 ©   (2002-09-16 11:50) [2]

TProcessList = class
First : PProcessInfo;
Constructor Create; - Там есть First := nil?
Procedure Add_PInfo(AInfo:TProcessEntry32);
Function DuplicateExist(AInfo:PProcessInfo):boolean;
Destructor Destroy;reintroduce;
end;



 
Cobalt ©   (2002-09-16 17:52) [3]


> REA (16.09.02 10:59)
> А не из DLL код вызывается?
нет

> Alx2 © (16.09.02 11:50)
> TProcessList = class
> First : PProcessInfo;
> Constructor Create; - Там есть First := nil?
Да
Вот последняя версия "этого дела": http://cobalt747.narod.ru/ProcessViewer.zip
Такое впечатление, что память либо не выделяется, либо теряется



 
REA   (2002-09-16 17:57) [4]

FullName:=Application.ExeName - а если просто строку туда? Может что то с потоками?


 
Cobalt ©   (2002-09-16 23:32) [5]

REA (16.09.02 17:57)
Вот это я и пробовал, простую, стопудово существующую строку.
Никак потоков нет, по таймеру(уже по кнопке;) пытаюсь заполнить связанный список.
причем
with tmp^ do
begin
PID:=AInfo.th32ProcessID;
OwnPID:=AInfo.th32ParentProcessID;
Checked:=false;
Next:=nil;// До этого все в порядке
FullName:=Application.ExeName;
Здесь происходит AV

Интересное дело: комментирую операцию со строками - список работает (проверял по PID процессов)


 
Alx2 ©   (2002-09-17 07:09) [6]

>Cobalt © (16.09.02 23:32)
sharemem?


 
Cobalt ©   (2002-09-17 12:26) [7]

Alx2 © (17.09.02 07:09)

>Cobalt © (16.09.02 23:32)
sharemem?

попробовал добавить этот модуль - стала выскакивать ошибка EInvalidPointer !при закрытии формы! (обработчиков событий на это нет), так что это не то ;(

Заменил record на Class - ошибка пропала!
Это наверное, Борланд классы продвигает таким путем...
http://cobalt747.narod.ru/ProcessViewer.zip (4,83 КБ)


 
REA   (2002-09-17 12:33) [8]

Мистика. Видимо надо смотреть как остальное сделано. Я обычно делаю TObjectList наследника и не вожусь со списками. Тем более что всякие очереди списки хэши стэки и бэги там есть.


 
Alx2 ©   (2002-09-17 12:37) [9]

>Cobalt © (17.09.02 12:26)
Нашел я твои ошибки :)

record оставь в покое.

Деструктор объяви как
Destructor Destroy; override;

И причина глюка - вместо GetMem используй New
Вот как здесь:

procedure TProcessList.Add_PInfo(AInfo: TProcessEntry32);
var tmp: PProcessInfo;
begin
if First = nil
then
begin
New(First);
tmp := First;
end
else
begin
tmp := First;
while tmp.Next <> nil do
tmp := tmp.Next;
New(tmp.Next);
tmp := tmp.Next;
end;
with tmp^ do
begin
PID := AInfo.th32ProcessID;
OwnPID := AInfo.th32ParentProcessID;
Checked := false;
Next := nil;
try
//SetLength(FullName,length(AInfo.szExeFile));
FullName := Application.ExeName;
// FullName:=AInfo.szExeFile;
except
end
end;
end;


 
Alx2 ©   (2002-09-17 12:38) [10]

Еще вдогонку:
Парной к New является Dispose.


 
Alx2 ©   (2002-09-17 13:32) [11]

Хотя принципиальной разницы с GetMem быть не должно. Надо посмотреть еще.
Но факт: с заменой Getmem на New все заработало :)


 
Alx2 ©   (2002-09-17 13:47) [12]

Нашел разницу!
В ходе работы New вызывается initializeArray, где и происходит недостающее при GetMem таинство :)


 
REA   (2002-09-17 15:20) [13]

Т.е. строки в записях с GetMem вообще нельзя хранить?
Не встречал такой информаци...


 
Cobalt ©   (2002-09-18 00:40) [14]

>Alx2 ©
Спасибо. Просто при выборе GetMem/New я считал, что New - это больше для объектов(осталось еще с ТР 7.0). А так как у меня были записи, то решил использовать GetMem. Вот тебе и опыт 8-((


 
Alx2 ©   (2002-09-18 07:30) [15]

>REA (17.09.02 15:20)
>Т.е. строки в записях с GetMem вообще нельзя хранить?
Видимо, это связано с заполнением структуры RTTI.
В частности,в D6 в ходе выполнения New вызывается

procedure _InitializeRecord(p: Pointer; typeInfo: Pointer);
var
FT: PFieldTable;
I: Cardinal;
begin
FT := PFieldTable(Integer(typeInfo) + Byte(PTypeInfo(typeInfo).Name[0]));
for I := FT.Count-1 downto 0 do
_InitializeArray(Pointer(Cardinal(P) + FT.Fields[I].Offset), FT.Fields[I].TypeInfo^, 1);
end;

где _InitializeArray:

const
tkLString = 10;
tkWString = 11;
tkVariant = 12;
tkArray = 13;
tkRecord = 14;
tkInterface = 15;
tkDynArray = 17;

procedure _InitializeArray(p: Pointer; typeInfo: Pointer; elemCount: Cardinal);
{$IFDEF PUREPASCAL}
var
FT: PFieldTable;
begin
if elemCount = 0 then Exit;
case PTypeInfo(typeInfo).Kind of
tkLString, tkWString, tkInterface, tkDynArray:
while elemCount > 0 do
begin
PInteger(P)^ := 0;
Inc(Integer(P), 4);
Dec(elemCount);
end;
tkVariant:
while elemCount > 0 do
begin
PInteger(P)^ := 0;
PInteger(Integer(P)+4)^ := 0;
PInteger(Integer(P)+8)^ := 0;
PInteger(Integer(P)+12)^ := 0;
Inc(Integer(P), sizeof(Variant));
Dec(elemCount);
end;
tkArray:
begin
FT := PFieldTable(Integer(typeInfo) + Byte(PTypeInfo(typeInfo).Name[0]));
while elemCount > 0 do
begin
_InitializeArray(P, FT.Fields[0].TypeInfo^, FT.Count);
Inc(Integer(P), FT.Size);
Dec(elemCount);
end;
end;
tkRecord:
begin
FT := PFieldTable(Integer(typeInfo) + Byte(PTypeInfo(typeInfo).Name[0]));
while elemCount > 0 do
begin
_InitializeRecord(P, typeInfo);
Inc(Integer(P), FT.Size);
Dec(elemCount);
end;
end;
else
Error(reInvalidPtr);
end;
end;

Короче говоря, модуль system.pas вносит полную ясность в происходящее. Только почему в help ничего не сказано о столь значительной разнице между getmem и new?


 
REA   (2002-09-18 10:23) [16]

Ему надо видимо мусор собирать динамический и создавать заголовки массивов, а GetMem это не умеет.



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

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

Наверх




Память: 0.51 MB
Время: 0.015 c
14-98270
AL2002
2002-09-02 17:28
2002.09.30
Есть какие-то тосты для программеров?


1-98179
AndreyS
2002-09-17 18:31
2002.09.30
Упаковщики exe


1-98150
Алексей Ким
2002-09-17 15:22
2002.09.30
WideString


3-97952
wed
2002-09-07 18:53
2002.09.30
Как сгруппировать данные по неделям ?


1-98031
LEV
2002-09-18 21:56
2002.09.30
ВОПРОС