Форум: "Основная";
Текущий архив: 2002.09.30;
Скачать: [xml.tar.bz2];
ВнизПроблема со строками 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
Здесь происходит AV
begin
PID:=AInfo.th32ProcessID;
OwnPID:=AInfo.th32ParentProcessID;
Checked:=false;
Next:=nil;// До этого все в порядке
FullName:=Application.ExeName;
Интересное дело: комментирую операцию со строками - список работает (проверял по 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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.007 c