Ссылается ли указатель на компонент?

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Re: Ссылается ли указатель на компонент?

Сообщение jakyro » 23.08.2016 22:28:35

скалогрыз писал(а):Мне кажется ты тестировал на тестах, которые ты подогнал под ответ, вместо тех тестов, которые мы тебе рекомендуем.
У тебя сильно секретный/сложный скрипт, может ты тестовый скрипт (именно скрипт, а не паскаль код) выложишь?

Просто я понимаю как это работает и знаю, что это будет работать на тестах, которые я провёл отдельно...
Я вообще спал всё это время и ничего, кроме тестов, ещё не делал со времени заданного вопроса.
Но специально для тебя, я набросал сырой тест, в котором ты можешь убедиться, что оно работает.
А так же ты можешь провести другие тесты, чтобы выявить ситуации при которых данный способ не будет работать. И конечно, проверять класс на nil - это ерунда, нужно реализовать более конкретный способ, с конкретными классами, но этож тест...

Код: Выделить всё
function CmpCreate: PtrInt;
begin
  Result := PtrInt(TForm.Create(Application));
end;

procedure CmpDelete(cmp: PtrInt);
var
  vcmp: PVmt;
begin
  vcmp := nil;
  vcmp := PVmt(cmp);
  if vcmp^.vClassName <> nil then
  begin
    TForm(cmp).Free;
    ShowMessageFmt('Объект %d успешно удален.', [cmp]);
  end
  else
    ShowMessageFmt('Объект %d уже был удалён!', [cmp]);
end;

procedure TForm1.FormClick(Sender: TObject);
var
  cmp: PtrInt;
begin
  cmp := CmpCreate;
  CmpDelete(cmp);
  CmpDelete(cmp);
end; 


Добавлено спустя 1 минуту 38 секунд:
Ну и кстати, результат:
Код: Выделить всё
cmp := CmpCreate;
CmpDelete(cmp); { Объект %s успешно удален. }
CmpDelete(cmp); { Объект %s уже был удалён! }

А так же можно подумать над способом удаления, я не говори что конкретно .Free будет использоваться. Всё это будет тестироваться и т.д., выявляться более стабильный способ.
Аватара пользователя
jakyro
новенький
 
Сообщения: 38
Зарегистрирован: 22.08.2016 08:04:21

Re: Ссылается ли указатель на компонент?

Сообщение скалогрыз » 23.08.2016 23:02:39

jakyro писал(а):Но специально для тебя, я набросал сырой тест, в котором ты можешь убедиться, что оно работает.


ну тогда перейдём к тесту зуба №2
Код: Выделить всё
{$mode delphi}
uses SysUtils;

function isValidObjInst(cmp: Pointer): Boolean;
var
  vcmp: PVmt;
begin
  vcmp := PVmt(cmp);
  Result:=Assigned(vcmp^.vClassName);
end;

var
  i   : PtrUInt;
  ro  : integer; // real objects
  fo  : integer; // not objects
  ec  : integer; // exceptions
const
  MB =  (1024 * 1024);
begin
  ec:=0; ro:=0; fo:=0;
  writeln('checking  mem for objects ',low(PtrUInt) ,' ',high(PtrUInt) );
  for i:=low(PtrUInt) to high(PtrUInt) do
    try
      if (i mod MB) = 0 then begin
        write('Mb checked: ', i div MB,' ' );
        write('True objects: ', ro,' ' );
        write('Fake objects: ', fo,' ' );
        writeln('Exceptions:   ', ec,' ' );
      end;
      if isValidObjInst(Pointer(i))
        then inc(ro)
        else inc(fo);
    except
      inc(ec);
    end;
    write('True objects: ', ro,' ' );
    write('Fake objects: ', fo,' ' );
    writeln('Exceptions:   ', ec);
end.


Ожидаемый результат. True objects Должено быть равно 0.
Количество Fake Objects + Exceptions должно равняться high(PtrUInt).
Что у тебя получается?

Замечу isValidObjInst() написан в соответствии с CmpDelete(). И действительно проверять класс на nil - это ерунда, то ведь это только тест!
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Ссылается ли указатель на компонент?

Сообщение jakyro » 23.08.2016 23:48:29

Ну да, тест не идеален, выявлены случаи когда выдает и nil в vcmp и не структуру...
А то что ты понаписал, ты как мне предлагаешь это тестировать? Делать консольное приложение, в то время когда у меня не консольное?
Я ведь нигде не говорил что это конечный, 100% рабочий результат и т.п.
Я говорил, что вот так сработало, если кто знает способ надежней пишите и т.п.
Конечно всё это будет выявляться во время тестов и доработки.
Нужно доработать в случае 0 или 1234, ну и пройтись тем же тестом по всему размеру...
И я не просто так присваивал nil для vcmp, а из-за того что если указатель не верен, то вся структура забивается максимальным значением. А также нужно добавить vcmp проверку на nil, а также проверку на доступность структыуры... или вообще просто найти альтернативу.

Я тут с вашими тестами - ничего не делаю в своём проекте. Просто сижу и вам что-то доказываю, вместо того чтобы самому уже давно всё реализовать...
Сделать нормальный тест, альтернативный. Если так не сработало, это не значит что никак не сработает и ваш вариант с кучей проблем типа лучше. Просто сделаю немного иначе.
Аватара пользователя
jakyro
новенький
 
Сообщения: 38
Зарегистрирован: 22.08.2016 08:04:21

Re: Ссылается ли указатель на компонент?

Сообщение скалогрыз » 24.08.2016 00:00:22

jakyro писал(а):Я тут с вашими тестами - ничего не делаю в своём проекте. Просто сижу и вам что-то доказываю, вместо того чтобы самому уже давно всё реализовать...

заметь, что мы с ТВОИМИ тестами (ведь для тебя тестируем!!!) тоже ничерта в своих проектах не сделали. А ведь сидим и пытаемся тебе что-то доказывать и помогать!

jakyro писал(а):Я ведь нигде не говорил что это конечный, 100% рабочий результат и т.п.

Ну... как бы не говорил, ты сказал что нашёл "Решение Сам". "Решение" обычно подразумевается как 100% рабочий результат!
НО все имеют право на ошибку, и любые доработки к решению, мы здесь для тебя с радостью потестируем, если не жалко будет поделиться.

jakyro писал(а):Делать консольное приложение, в то время когда у меня не консольное?

у меня язык чешеться пофлудить на тему консоль-не консоль (и что разницы между ними нет), но не буду :D
Хотя, ты без труда, мой консольный пример можешь на GUI переложить.
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Ссылается ли указатель на компонент?

Сообщение jakyro » 24.08.2016 00:10:13

скалогрыз писал(а):заметь, что мы с ТВОИМИ тестами (ведь для тебя тестируем!!!) тоже ничерта в своих проектах не сделали. А ведь сидим и пытаемся тебе что-то доказывать и помогать!

Нет, вы всё это время пытались навязать свой способ, а не найти способ проверить указатель.
скалогрыз писал(а):Ну... как бы не говорил, ты сказал что нашёл "Решение Сам". "Решение" обычно подразумевается как 100% рабочий результат!
НО все имеют право на ошибку, и любые доработки к решению, мы здесь для тебя с радостью потестируем, если не жалко будет поделиться.

Нет, ничего не подразумевает.
Если ты нашёл решение прилепить ручку кружки клеем, это не значит, что тот же клей подойдёт для других ситуаций. Всё нужно тестировать и подбирать клей, дорабатывать. (нет, я не нанюхался тут клея во время своих тестов :mrgreen: )
скалогрыз писал(а):у меня язык чешеться пофлудить на тему консоль-не консоль (и что разницы между ними нет), но не буду :D
Хотя, ты без труда, мой консольный пример можешь на GUI переложить.

Ну типа есть другие библиотеки и т.д. И мне придётся либо переделывать твой код (как ты верно подметил, но не додумался об этом раньше), либо пихать библиотеки, либо делать консольное приложение.
Аватара пользователя
jakyro
новенький
 
Сообщения: 38
Зарегистрирован: 22.08.2016 08:04:21

Re: Ссылается ли указатель на компонент?

Сообщение скалогрыз » 24.08.2016 00:15:30

jakyro писал(а):Нет, вы всё это время пытались навязать свой способ, а не найти способ проверить указатель.

Конечно! И продолжаю это делать!

Вот смотри тест.
Я тебе советую его сравнить по производительности с предыдущим тестом.
Ужас будет в том, что этот работает быстрее, потому что код не вываливается с exception-ами (если ты смотрел предыдущий тест, то количество ec, у тебя скорей всего было больше 0)
Код: Выделить всё
{$mode delphi}
uses SysUtils, AVL_Tree;

var
  r : TAVLTree;
procedure InitRegistry;
begin
  r:=TAVLTree.Create;
end;

procedure ReleaseRegistry;
begin
  r.Free;
end;

procedure RegisterPointer(cmp: Pointer);
begin
  r.Add(cmp);
end;

procedure UnregisterPointer(cmp: Pointer);
begin
  r.Remove(cmp);
end;

function isValidObjInst(cmp: Pointer): Boolean;
begin
  Result:=Assigned(r.FindPointer(cmp));
end;

var
  i   : PtrUInt;
  ro  : integer; // real objects
  fo  : integer; // not objects
  ec  : integer; // exceptions
const
  MB =  (1024 * 1024);
begin
  InitRegistry;
  ec:=0; ro:=0; fo:=0;
  writeln('checking  mem for objects ',low(PtrUInt) ,' ',high(PtrUInt) );
  // define testobj to see True object in action
  {.$define testobj}

  {$ifdef testobj}
  RegisterPointer(r);
  for i:=PtrUInt(r)-4 to PtrUInt(r)+4 do
  {$else}   
  for i:=low(PtrUInt) to high(PtrUInt) do
  {$endif}
    try
      if (i mod MB) = 0 then begin
        write('Mb checked: ', i div MB,' ' );
        write('True objects: ', ro,' ' );
        write('Fake objects: ', fo,' ' );
        writeln('Exceptions:   ', ec,' ' );
      end;
      if isValidObjInst(Pointer(i))
        then inc(ro)
        else inc(fo);
    except
      inc(ec);
    end;
    write('True objects: ', ro,' ' );
    write('Fake objects: ', fo,' ' );
    writeln('Exceptions:   ', ec);
  ReleaseRegistry;
end.

Прикрутить этот Тест к Гуям? просто забавы ради?

jakyro писал(а):Ну типа есть другие библиотеки и т.д. И мне придётся либо переделывать твой код (как ты верно подметил, но не додумался об этом раньше), либо пихать библиотеки, либо делать консольное приложение.

я ничего не понял здесь, но предлагаю не тратить время на обсуждение.
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Ссылается ли указатель на компонент?

Сообщение jakyro » 24.08.2016 00:29:09

скалогрыз писал(а):если ты смотрел предыдущий тест, то количество ec, у тебя скорей всего было больше 0

Нет, просто выбивало ошибку, так как vcmp^ не являлось структурой.

Добавлено спустя 8 минут 15 секунд:
И нет, я всё равно не буду реализовывать какое-то хранилище, так как это большая портянка (не то что ты там написал, а при реальной работе с компонентами) и в добавок возникнут проблемы со стороны скриптов.

Например:
Код: Выделить всё
form = CreateForm       { Тут ты записал указатель на форму в память }
canvas = form.Canvas    { Получил экземпляр класса канваса в отдельную переменную }
CmpDelete(form)         { Где-то там удалил компонент, очистил указатель }
canvas.MoveTo(0, 0)     { Получил ошибку, так как владелец удалён, а за этим указателем ты никак не следил } 

Можно и это обыграть, всё можно обыграть, но это дополнительный склад портянок.

Добавлено спустя 52 секунды:
скалогрыз писал(а):Я тебе советую его сравнить по производительности с предыдущим тестом.

И да. Производительность - мне вообще не важна. Так как скриптовой язык не более производителен чем оба этих способа.
Аватара пользователя
jakyro
новенький
 
Сообщения: 38
Зарегистрирован: 22.08.2016 08:04:21

Re: Ссылается ли указатель на компонент?

Сообщение скалогрыз » 24.08.2016 00:45:52

jakyro писал(а):Нет, просто выбивало ошибку, так как vcmp^ не являлось структурой.

опять под отладчиком запускал? :D

jakyro писал(а):И нет, я всё равно не буду реализовывать какое-то хранилище, так как это большая портянка (не то что ты там написал, а при реальной работе с компонентами) и в добавок возникнут проблемы со стороны скриптов.

очевидно зависит от того как реализован вызов "form.Canvas" и "Canvas.MoveTo" на уровне скрипта.
Если Canvas.MoveTo идёт через обёртку (а ему вообще-то нужно идёт через обёртку, ибо скрипт!), то ты всегда можешь проверить правильность "Canvas".
Соответственно form.Canvas, должен регистрировать объект (и тут тонкость! с завязкой на существования родителя! ууууу - реализуется на раз!)

Уж не Pascal-ли скрипт ты используешь?

пример в аттаче, можешь потестировать меняя OnClick для кнопок Test1 и Test2.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Ссылается ли указатель на компонент?

Сообщение jakyro » 24.08.2016 00:57:53

скалогрыз писал(а):очевидно зависит от того как реализован вызов "form.Canvas" и "Canvas.MoveTo" на уровне скрипта.
Если Canvas.MoveTo идёт через обёртку (а ему вообще-то нужно идёт через обёртку, ибо скрипт!), то ты всегда можешь проверить правильность "Canvas".
Соответственно form.Canvas, должен регистрировать объект (и тут тонкость! с завязкой на существования родителя! ууууу - реализуется на раз!)

Ну и я о том же. Писать дополнительный портянки обработки портянок, вместо валидации указателя.

скалогрыз писал(а):Уж не Pascal-ли скрипт ты используешь?

Нет. Более продвинутый язык, но не хочу акцентировать на этом внимание, чтоб не трубить об этом везде, а сообщить уже в бета тесте, или в релизе. Ну мож и что бы никто не украл мою, конечно же, гениальную идею :evil:
А этот скрипт был выдуман, как и синтаксис, чтоб примерно представляли о чём я.

скалогрыз писал(а):пример в аттаче

Не лень же тебе было всё это сидеть писать, что мне всё равно будет не интересно, так как я фанатик своей идеи проверки указателя :roll:
Аватара пользователя
jakyro
новенький
 
Сообщения: 38
Зарегистрирован: 22.08.2016 08:04:21

Re: Ссылается ли указатель на компонент?

Сообщение скалогрыз » 24.08.2016 01:10:27

jakyro писал(а):Ну и я о том же. Писать дополнительный портянки обработки портянок, вместо валидации указателя.

ты не объяснил как наружу выдаются "Form.Canvas" и "Canvas.MoveTo".

jakyro писал(а):Не лень же тебе было всё это сидеть писать, что мне всё равно будет не интересно, так как я фанатик своей идеи проверки указателя

а я фанат идеи хорошего кода - написал - отладил - забыл, а не писать хаки от версии к версии компилятора.
трудозатраты, кстати, 15 минут.
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Ссылается ли указатель на компонент?

Сообщение jakyro » 24.08.2016 01:30:30

скалогрыз писал(а):ты не объяснил как наружу выдаются "Form.Canvas" и "Canvas.MoveTo".

Потому что я знаю, что ты ведёшь к тому, чтобы и тут сделать слежку за указателями.
Ну возможно, возмооооожно, стоит сделать так. Ну а если про ту производительность говорить, то что будет производительней, искать указатель среди тысяч или проверить указатель хаком? Скорее всего хак будет производительней, но это смотря как он реализован.
Наверняка, всякие гуру pascal знают как это можно сделать, возможно знают и специализированные функции.
Но, наверно, таких людей мало, судя по тому что в интернете на подобный вопрос нет конкретного ответа, максимум что нашёл это те же хаки (ну или реализация другой задачи, с хранилищем указателей).

скалогрыз писал(а):а я фанат идеи хорошего кода - написал - отладил - забыл, а не писать хаки от версии к версии компилятора.

Действительно. И году не прошло, с моменту последнего обновления. А vectorcall там нет в планах?
Аватара пользователя
jakyro
новенький
 
Сообщения: 38
Зарегистрирован: 22.08.2016 08:04:21

Re: Ссылается ли указатель на компонент?

Сообщение zub » 24.08.2016 01:39:53

Скорее всего хак будет производительней, но это смотря как он реализован.

Нет такого хака. До тебя еще не дошло? Тогда надо переводиться из фанатиков в дурачки((
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Ссылается ли указатель на компонент?

Сообщение jakyro » 24.08.2016 01:44:32

zub писал(а):Нет такого хака. До тебя еще не дошло?

А бог есть?
Аватара пользователя
jakyro
новенький
 
Сообщения: 38
Зарегистрирован: 22.08.2016 08:04:21

Re: Ссылается ли указатель на компонент?

Сообщение zub » 24.08.2016 01:47:07

Есть вещи которые можно проверить тестом, есть которые нельзя.
Мы тут говорим о том что легко проверяется. И результаты в пользу существования "хака" есть только у тебя в голове
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Ссылается ли указатель на компонент?

Сообщение jakyro » 24.08.2016 01:56:07

zub писал(а):Есть вещи которые можно проверить тестом, есть которые нельзя.
Мы тут говорим о том что легко проверяется. И результаты в пользу существования "хака" есть только у тебя в голове

Ну просто ты утверждаешь, что ты всё знаешь, я и решил спросить, мож и это тоже знаешь...
А утверждаешь что "всё знаешь" потому, что пытаешься доказать что хака нет, в то время, когда кругом пишут хаки на подобную тему.
А ты ведь не можешь знать всё то, что реализовали во всём мире, то что есть в интернете и то чего нет, секреты, трюки и т.д. Но тем не минее утверждаешь что такого хака нет. Эгоизм?
Если ты не видел хака, это не значит что его нет или он не возможен...

Ну если хака нет, то тогда его стоит написать.

Добавлено спустя 5 минут 17 секунд:
zub писал(а):Есть вещи которые можно проверить тестом, есть которые нельзя.

Я ведь вижу, что отладчик понимает, что этот адрес он может читать, а другой нет, один является структурой, а другой нет. Вот подобное поведение и нужно реализовать в валидаторе, такой встроенный мини отладчик.
Вот поэтому, немножко логически подумав, я могу предположить, что такое возможно.

И это работает без крашей, пока не начинаешь обращаться к памяти. Вот нужно реализовать такой способ, который бы основывался не на работе с полученной структурой, так как выдаст ошибку, если указатель кривой, а на анализе памяти.
Аватара пользователя
jakyro
новенький
 
Сообщения: 38
Зарегистрирован: 22.08.2016 08:04:21

Пред.След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 231

Рейтинг@Mail.ru