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

Наверх





Память: 0.49 MB
Время: 0.009 c
7-98367
SerVS
2002-07-18 23:12
2002.09.30
Адрессная книга Outlook Express


4-98410
Lamer86
2002-08-15 16:57
2002.09.30
ListBox


3-97958
PAVELSIN
2002-09-08 19:17
2002.09.30
Имеются клиперовские файлы DBaseIII+ c индексами.


3-97976
Bishop
2002-09-07 16:23
2002.09.30
Экспорт в Excel


1-98172
Taa
2002-09-17 18:14
2002.09.30
Работа с массивами Variant





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский