Очередная "Загадочная ошибка" ...

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

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

Очередная "Загадочная ошибка" ...

Сообщение Alex2013 » 12.07.2017 21:41:14

Есть вот такой код ...
Код: Выделить всё
Function TForm1.InputStr(Q,D:String;W:Integer):String;
Var
L,l1,l2:TLabel;
E:TEdit;
B:TButton;
EK:TkeyEvent;
rF:TForm;
begin

rF:=TForm.Create(Application);
rF.Top:=top+20;
rf.Left:=Left+10;
rF.Width:=W;
rF.Height :=100;
// ....
if  rF.ShowModal=mrOk then
  inputStr:=e.text else inputStr:=D;
rF.Free;
end ;
procedure TForm1.VST3ColumnClick(Sender: TBaseVirtualTree;
  Column: TColumnIndex; Shift: TShiftState);

var
Data: PLCLTextData;
S,S1,s2:String;
PS:PString;
begin
if   VST3.FocusedNode =  nil then exit;
Data := VST3. GetNodeData(VST3.FocusedNode);

if ssCtrl in Shift then  begin
         PS:= Data^.T2 ;    if PS<>Nil then S1:=PS^ else S1:='' ;

        //     DisposeStr(PS) ;// ТАК НЕ РАБОТАЕТ !

        S2:=InputStr(Data^.T1^,s1,220);
        Data^.T2 :=   NewStr(S2); 

        DisposeStr(PS) ;// ТАК РАБОТАЕТ ...
 
end else
   VST3.EditNode(vst3.FocusedNode,1);

end;


Суть вот в чем
if rF.ShowModal=mrOk then в InputStr...
Выдает исключение при вызове очистки строки (DisposeStr(PS) ; ) перед вызовом S2:=InputStr(Data^.T1^,s1,220);

Честно говоря я в полном замешательстве, как вообще может влиять процедура DisposeStr на код в другом методе :?: ...никак не связный с ней даже данными ( тем более что если поставить DisposeStr после вызова InputStr все работает ... ) :roll:
Alex2013
энтузиаст
 
Сообщения: 697
Зарегистрирован: 03.04.2013 11:59:44

Re: Очередная "Загадочная ошибка" ...

Сообщение Снег Север » 12.07.2017 21:59:44

Ваш Кэп подсказывает, что обращение к памяти где-до влазит не туда. Поэтому лично я никогда всеми этими NewStr и прочими сишными извратами не пользуюсь. Ибо разгребать за ними...
Аватара пользователя
Снег Север
энтузиаст
 
Сообщения: 948
Зарегистрирован: 27.11.2007 16:14:47

Re: Очередная "Загадочная ошибка" ...

Сообщение Лекс Айрин » 12.07.2017 22:01:03

Попробуй заголовок написать так:

Код: Выделить всё
Function TForm1.InputStr(Var Q,D:String; Var W:Integer):String; // или const, если параметры не меняются.

А вообще, возможно стоит проверить программу на утечки.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 4092
Зарегистрирован: 19.02.2013 16:54:51

Re: Очередная "Загадочная ошибка" ...

Сообщение olegy123 » 12.07.2017 22:22:44

Код: Выделить всё
PS:= Data^.T2;
..
DisposeStr(PS)..

Что в Data^.T2?

Вообще то с указателями работать - экстремально. Если с обычными переменными - компилятор постарается вырулить, или задаст море вопросов при компиляции. А с указателями - это жанглирование с шариками.. интуитивно понимать что в руке, а что в воздухе и когда надо ловить.
olegy123
энтузиаст
 
Сообщения: 720
Зарегистрирован: 25.02.2016 12:10:20

Re: Очередная "Загадочная ошибка" ...

Сообщение Alex2013 » 12.07.2017 22:41:26

olegy123 писал(а):
Код: Выделить всё
PS:= Data^.T2;
..
DisposeStr(PS)..

Что в Data^.T2?

TLCLTextData = record
T1: PString;
T2: PString;
DT : Integer;
end;
PLCLTextData = ^TLCLTextData;

Вообще то с указателями работать - экстремально. Если с обычными переменными - компилятор постарается вырулить, или задаст море вопросов при компиляции. А с указателями - это жанглирование с шариками.. интуитивно понимать что в руке, а что в воздухе и когда надо ловить.


Если интересно более подробно откуда что взялось глянь в пример ТУТ ...
(Там ошибка еще не исправлена ) На прямую с указателями работать нужно уметь, это факт ... но в старых версиях BP вообще все на них держалось и что характерно никуда ничего "не падало " ....

Но непонятно откуда вообще это исключение может лезть ?
Разумеется, само динамическое создание формы, это что-то чуток "читреское" (так что грешу именно на него ) но ведь всюду работает ! А тут облом ....
Alex2013
энтузиаст
 
Сообщения: 697
Зарегистрирован: 03.04.2013 11:59:44

Re: Очередная "Загадочная ошибка" ...

Сообщение LearnMagic » 12.07.2017 23:03:46

Alex2013 писал(а):... Честно говоря я в полном замешательстве, как вообще может влиять процедура DisposeStr на код в другом методе ...

"Восток - дело тонкое, Петруха".
См реализацию работы со строками. После S1:=PS^ фактического копирования данных не происходит, как следствие, после DisposeStr(PS) S1 указывает на уже не существующие данные.
LearnMagic
новенький
 
Сообщения: 33
Зарегистрирован: 10.11.2016 23:13:38

Re: Очередная "Загадочная ошибка" ...

Сообщение Alex2013 » 13.07.2017 01:16:03

Или я что-то не понял ....Или вы хотите сказать что S1:=PS^ передает не данные, а УКАЗАТЕЛЬ ? Но это же бред какой-то ...
Кстати предполагая подобное пробовал для теста так S1:='0'+PS^ ; ... DisposeStr(PS) результат получался тот же .
То есть если вы правы то получается что для гарантии нужно писать вместо S1:=PS^ что-то вроде S1:=Copy(PS^,1,Length(PS^)); :?:
Брєд... :idea: Хотя наверное можно и так S1:=String(PS^); :roll:
Зы
...но интересно, короче ухожу в оффлайн пробовать .... :idea:

Добавлено спустя 1 час 7 минут 51 секунду:
1 Рецепт с Var и Const - провал
2 тоже самое с моими домыслами ...
(Единственная идея странно отложенное до выхода на модальный диалог действие ... но почему так происходит неясно ) :roll:
Alex2013
энтузиаст
 
Сообщения: 697
Зарегистрирован: 03.04.2013 11:59:44

Re: Очередная "Загадочная ошибка" ...

Сообщение vitaly_l » 13.07.2017 08:14:52

Alex2013 писал(а):PS:= Data^.T2 ;
// DisposeStr(PS) ;// ТАК НЕ РАБОТАЕТ !
Data^.T2 := NewStr(S2);
DisposeStr(PS) ;// ТАК РАБОТАЕТ !

Чехарда в коде.

Строкой кода: DisposeStr(PS) ; - вы пытаетесь удалить глобальный указатель, который передали в PS. И соответственно, она падает, т.к. у PS и памяти, вы его удалили, а в Data он остался. Ну а когда, вы перед DisposeStr присваиваете глобальному новый указатель, она перестаёт падать.
Последний раз редактировалось vitaly_l 13.07.2017 09:24:53, всего редактировалось 1 раз.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3064
Зарегистрирован: 31.01.2012 16:41:41

Re: Очередная "Загадочная ошибка" ...

Сообщение zub » 13.07.2017 09:24:17

Alex2013
Это не ошибка. Это закономерный результат работы говнокода((
Если ты хочешь чтоб ктото вникал в твои творения, будь добр в первом посте выставлять минимальный компилируемый пример воспроизводящий вылет. А не ведро какаши как у тебя сейчас. Натыкано всяких тлабелов, тбутонов, лефтов, ригтов и прочих апликейшенов не имеющих к делу никакого отношения... а объявления data нет...

Добавлено спустя 4 минуты 55 секунд:
viewtopic.php?t=11801&view=unread#p103605
>>3 D^.Data:=NewStr(V); огребешь тут проблем
Таки мой телепатор еще огого))
zub
долгожитель
 
Сообщения: 2257
Зарегистрирован: 14.11.2005 23:51:26

Re: Очередная "Загадочная ошибка" ...

Сообщение MysticCoder » 13.07.2017 10:55:47

Код: Выделить всё
PS:= Data^.T2 ;    if PS<>Nil then S1:=PS^ else S1:='' ;
        //     DisposeStr(PS) ;// ТАК НЕ РАБОТАЕТ !
        S2:=InputStr(Data^.T1^,s1,220);

я не шибко в этом шарю, но возможно здесь в S1 не происходит реального копирования значений, а просто присваивается ссылка на PS, мол данные по этому адресу хранятся. Потом уже ты эти данные через DisposeStr(PS) освобождаешь, и S1 получается указывает на невалидные данные, которые ты пытаешься использовать уже во втором методе, а именно inputStr:=D;.

Для явного копирования есть какой то метод который гарантированно возвращает новую строку, NewStr что ли...
MysticCoder
постоялец
 
Сообщения: 112
Зарегистрирован: 14.09.2013 00:20:28

Re: Очередная "Загадочная ошибка" ...

Сообщение Alex2013 » 13.07.2017 13:56:41

2ZUB: Проснулся и зубом как цикнет ... :D но кое в чем твоя правда... и сам думаю что нужно сделать "чистый" пример .... Но ты по моему просто не "вник" ... И тут совсем другой случай .
(Это вообще вспомогательная табличка... основной код с VT(VirtualTree ) работает как часы )
А еще раньше было так ...
TLCLTextData = record
T1: String;
T2: String;
DT : Integer;
end;
PLCLTextData = ^TLCLTextData;

И я внезапно отгреб проблем при превышении длинны строки относительно исходной ... Тоже от еще прикол ... :idea: казалось бы строка и в Африке строка ... Ага ! ЩаZ ! :idea: Память выделяется под "пустой тип" SizeOf (TLCLTextData )... а "длинные строки" по идее управляются "стандартно"... но не работает . Вот и пришлось делать с PString с ним в VT все работает ..

И еще со строками внутри InputStr все ок выбивает только тут if rF.ShowModal=mrOk then ...
Зы
2MysticCoder : "факир был пьян и фокус не удался " Так S1:=Copy(PS^,1,Length(PS^)); ТОЖЕ не работает ...
Alex2013
энтузиаст
 
Сообщения: 697
Зарегистрирован: 03.04.2013 11:59:44

Re: Очередная "Загадочная ошибка" ...

Сообщение MysticCoder » 13.07.2017 14:37:22

Alex2013 писал(а):2MysticCoder : "факир был пьян и фокус не удался " Так S1:=Copy(PS^,1,Length(PS^)); ТОЖЕ не работает ...


я ни на что не намекаю, но такой код:
Код: Выделить всё

var
  xs1 : string;
  xs2 : string;
begin
  xs1 := '123123123';
  xs2 := copy(xs1, 1, length(xs1));
  writeln(pint64(xs1)^, ' ', pint64(xs2)^);   


у меня выдает
Код: Выделить всё
3616728266422039089 3616728266422039089
MysticCoder
постоялец
 
Сообщения: 112
Зарегистрирован: 14.09.2013 00:20:28

Re: Очередная "Загадочная ошибка" ...

Сообщение wavebvg » 13.07.2017 14:42:13

Код: Выделить всё
Data: PLCLTextData;

Код: Выделить всё
DisposeStr(PS);

Строку хранить в ссылочном типе данных, создаваемом через New?
И как, по вашему, компилятор будет код для подсчета ссылок вставлять?
wavebvg
постоялец
 
Сообщения: 283
Зарегистрирован: 28.02.2008 04:57:35

Re: Очередная "Загадочная ошибка" ...

Сообщение Alex2013 » 13.07.2017 15:01:50

Там теперь так
TLCLTextData = record
T1: PString;
T2: PString;
DT : Integer;
end;
PLCLTextData = ^TLCLTextData;
...и PS:= Data^.T2 ;
(как было с с T1,T2: String; смотри ТУТ )

А рекорд распределяемый через GetMem это не я придумал ... это часть VT ..
Возможно я не полностью "горкнул"( то бишь вник в ) примеры из кусков которых пытаюсь лепить что-то свое ...
Но уж больно они там "углубленные" ,а мне от VT нужен только "ПропертиЕдитор" (Редактор свойств ) и то в значительно упрощенной комплектации...
Зы
"По качеству " кода , десу ...но это пока просто "исследование вопроса" даже не "рыба" а головастики какие-то ... :wink:

Ладно учапал делать чистый пример ...
Alex2013
энтузиаст
 
Сообщения: 697
Зарегистрирован: 03.04.2013 11:59:44

Re: Очередная "Загадочная ошибка" ...

Сообщение vitaly_l » 13.07.2017 15:24:33

Alex2013 писал(а):Ладно учапал делать чистый пример ...

Когда будете делать свой пример, прежде чем выложить его на форум, обязательно попробуйте вместо:
Код: Выделить всё
DisposeStr(PS) ; // ТАК НЕ РАБОТАЕТ

сделать:
Код: Выделить всё
PS:= Data^.T2 ;
...
Data^.T2 :=  nil;
DisposeStr(PS) ;
PS := nil;
Data^.T2 :=   NewStr(S2); 


/
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3064
Зарегистрирован: 31.01.2012 16:41:41

След.

Вернуться в Lazarus

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

Сейчас этот форум просматривают: Bing [Bot], kosteek и гости: 5

Рейтинг@Mail.ru