Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по Delphi (все версии) - часть 4

Автор: Frodo_Torbins
Дата сообщения: 13.04.2009 19:39
Kursist
Как минимум нужно знать сообщение об ошибке, чтобы появились идеи. А вообще попробуйте с EurekaLog свою программу погонять.
Автор: Kursist
Дата сообщения: 13.04.2009 20:44
Project ..exe faulted with message 'access violation at 0x... write of address... Process stoped. Use Step or Run to continue...

Скачал и проинсталлировал триал EurekaLog. Странное дело! Когда его активизировал - программа запустилась, нужное мне окно стало открываться, но стала возникать ошибка на совсем другом месте (на задании размера динамическому массиву, чего до этого не было!), в совсем другой форме и в другом объекте, который не связан с предыдущей формой... шаманство какое-то, но разобраться хочется! Когда EurekaLog деактивируешь, то приложение не запускается - стопорится на том же месте, где и раньше.


Автор: Frodo_Torbins
Дата сообщения: 13.04.2009 20:52
Kursist
Внимательно просмотрите все свои операции с памятью, похоже вы где то затираете лишнее. Еще "Range checking" включите.
Автор: Kursist
Дата сообщения: 13.04.2009 22:05
Frodo_Torbins
Спасибо, про "Range checking" забыл. Включил, но не помогло.
EurekaLog ловит ошибку на строке inc(self.fdate) - поле объекта типа Integer.

Очень смущает, как так, что без EurekaLog прога не запускается (ошибка при создании формы), а с EurekaLog запускается (что такое происходит?), а ошибка (возможно, только первая) при загрузки из файла, но эта процедура работала прежде без сбоев:

if FileExists(SPTFileName) then
begin
try
FStream:=TFileStream.Create(SPTFileName,fmOpenRead);
FStream.Position:=0;

FStream.Read(SPTKey,SizeOf(SPTKey));
if SPTKey<>'S'then
begin
MessageDlg('NOT STD FILE!',mtError, [mbOK],0);
FStream.Free;
exit;
end;

FStream.Read(SPTKey,SizeOf(SPTKey));
if SPTKey<>'P'then
begin
MessageDlg('NOT STD FILE!',mtError, [mbOK],0);
FStream.Free;
exit;
end;

FStream.Read(SPTKey,SizeOf(SPTKey));
if SPTKey<>'T'then
begin
MessageDlg('NOT STD FILE!',mtError, [mbOK],0);
FStream.Free;
exit;
end;

//inc(FSPTCount); {как вариант}
inc(self.FLoadedSPT); <-------------------------------------------------падает здесь

SetLength(FAnArray,FLoadedSPT); // 3-Dimension array arr[a]
SetLength(FAnArray[FLoadedSPT-1],1); //arr[a,b]
SetLength(FAnArray[FLoadedSPT-1,0],1); //arr[a,b,c]


Предположительно ошибка "плавающая" - вспомнил, что в одной из старых версий программы тоже вдруг перестала запускаться одна из форм, только на тот момент она оказалась "лишней"...вообщем, чувствую, надо будет долго-долго искать...
Автор: Frodo_Torbins
Дата сообщения: 13.04.2009 22:55
Kursist
Похоже вы все же где то трете память. До добавления EurekaLog затиралась память необходимая для создания формы, теперь на этом месте self.FLoadedSPT. Возможно на self.FLoadedSPT стоит поставить бряк на память, чтобы узнать откуда трется. Подробнее: Обработка ошибок.
Автор: Kursist
Дата сообщения: 13.04.2009 23:54
Спасибо Frodo_Torbins
Увы, еще не умею бороться с такими ошибками. Буду учиться.
А "поставить бряк на память" - это в EurekaLog "Catch Memory Leaks"?

Обнаружил, что и одна из форм перестала показываться.
Вообщем, всё порушилось.

Memory leak (утечка памяти) - выдало 2 сообщения:
Call stack:
address/module/unit/class/procedure

Memory Leak: Type= TLoader; Total Size=16; Count=1
.../LEditor.exe/FormMain.pas/TMainForm/FormCreate

Memory Leak: Type=TManager; TotalSize=400; Count=1

Это 2 моих класса, и у обоих утечка памяти при создании (так как ничего кроме инициализации они на данном этапе не делают).

SetLength(FTexRegionArr,0); - может это создавать утечку?
Автор: ShIvADeSt
Дата сообщения: 14.04.2009 01:18
Kursist

Цитата:
FStream.Read(SPTKey,SizeOf(SPTKey));
if SPTKey<>'S'then
begin
MessageDlg('NOT STD FILE!',mtError, [mbOK],0);
FStream.Free;
exit;
end;

FStream.Read(SPTKey,SizeOf(SPTKey));
if SPTKey<>'P'then
begin
MessageDlg('NOT STD FILE!',mtError, [mbOK],0);
FStream.Free;
exit;
end;

Не знаю, но может поможет. Ты пытаешься читать из потока несколько раз, при этом не проверяя конец ли потока или нет. Лучше всего получить размер потока и смотреть не конец ли.
Автор: V1s1ter
Дата сообщения: 14.04.2009 10:42
Kursist

Цитата:
Memory Leak: Type=TManager; TotalSize=400; Count=1
Это 2 моих класса, и у обоих утечка памяти при создании (так как ничего кроме инициализации они на данном этапе не делают).

Это означает, что то что было создано в этой процедуре, небыло потом гдето освобождено. Как правило если показывает в Create, то надо смотреть чегозабыл написать в Destroy.


Цитата:
SetLength(FTexRegionArr,0); - может это создавать утечку

Это утечку создавать не может, поскольку Ты говориш "выдели мне аж ноль байт памяти для FTexRegionArr". К стати если эта строка у тебя в XXXX.Create, a FTexRegionArr это переменная класса XXXX, то данная строка лишняя, посколику все переменные объекта при создании устанавливаются в ноль или его аналоги.
Автор: Kursist
Дата сообщения: 14.04.2009 11:04
ShIvADeSt.
Если говорить про файловый поток, то в данном случае, мне казалось, что достаточно проверки на существование файла if FileExists(SPTFileName). И если он существует, то идет проверка первых трех байтов для идентификации типа файла. Единственный случай, как мне кажется, который может вызвать ошибку - это файл размером до 3 байт (за идею проверки конца потока спасибо).

Но ошибка все-таки дело не в этом, а с утечкой памяти. Раньше слышал о таком явлении, но представить не мог, как это выглядит, а теперь вот знаю - когда приложение начинает глючить на прежде стабильных участках кода, как бы без видимых причин.

EurekaLog показал:
Memory Leak: Type= TLoader; Total Size=16; Count=1
Memory Leak: Type=TManager; TotalSize=400; Count=1

Приложение стало вылетать при старте, при загрузки одной из форм. До этого ничего криминального не создавалось, кроме других форм, и 2 объектов моих классов. Судя по информации по ссылке, что мне дал Frodo_Torbins
http://delphikingdom.com/asp/viewitem.asp?catalogid=1392
это такая ошибка, которая не была обнаружина всеми средствами VCL - то есть, приложение рушится (не всегда). Вот дочитаю статью и буду разбираться, но уже сейчас мне ясно, что проблема с выделением памяти для 3-мерного массива. До этого я использовал 3 вложенных друг в друга TList, но мне показалось, что такой код с массивами более симпатичен/проще/компактнее, но вот, напоролся на грабли с утечкой памяти.
Автор: V1s1ter
Дата сообщения: 14.04.2009 11:14
Kursist

Цитата:
Но ошибка все-таки дело не в этом, а с утечкой памяти. Раньше слышал о таком явлении, но представить не мог, как это выглядит, а теперь вот знаю - когда приложение начинает глючить на прежде стабильных участках кода, как бы без видимых причин.

Это не от утечек память, точнее если утечки не громадного масштаба.
Можно говорить о нарушении распределения памяти памяти. Memory Leak может иногда коствено указать где это произошло.

Цитата:
До этого я использовал 3 вложенных друг в друга TList, но мне показалось, что такой код с массивами более симпатичен/проще/компактнее, но вот, напоролся на грабли с утечкой памяти.

Утечки не причем, а вот запись в не выделенную память или чтение из нее это уже ближе к делу.
Утечка это не добавление участка памяти, который "утек", в список свободной памяти.
Только утечки размером в объем операвтивной памяти + размер файла подкачки - кое чего могут привести к ошибкам.
Автор: Kursist
Дата сообщения: 14.04.2009 11:16
V1s1ter

Цитата:
данная строка лишняя

ОК. Понял.

Добавлено:
V1s1ter

Цитата:
Это не от утечек память, точнее если утечки не громадного масштаба.
Можно говорить о нарушении распределения памяти...


Тогда, видимо, я не совсем правильно понимаю термин "утечка памяти", но, думаю, суть верна - происходит где-то нарушение распределения памяти. Логически меня устроило объяснение Frodo_Torbins
Цитата:
Похоже вы все же где то трете память. До добавления EurekaLog затиралась память необходимая для создания формы, теперь на этом месте self.FLoadedSPT. Возможно на self.FLoadedSPT стоит поставить бряк на память, чтобы узнать откуда трется...

мне многое прояснило
Цитата:
...где то трете память
- я назвал "утечкой", тем более, что EurekaLog показал Memory Leak.

На данном этапе стали сыпаться ошибки за ошибкой.
Сейчас проверяю все свои SetLength(), GetMem() и FreeMem()
Автор: Frodo_Torbins
Дата сообщения: 14.04.2009 14:10
Kursist
Утечка это немного другое. Например вы создаете объект, а потом ссылка на него где то теряется. Он, не удаленный, так и остается висеть в памяти мертвым грузом - это утечка. В вашем случае похоже утечки являются не причиной, а следствием (ну и плюс вылеты).
P.S. А статью я еще сам не дочитал, но уже сейчас вижу, сколько раньше делал ошибок
Автор: Kursist
Дата сообщения: 14.04.2009 16:40
Frodo_Torbins
Можете мне объяснить, как вообще происходит "затирание памяти". Что это такое? Как такое возможно, что происходит смещение ошибки (выглядит это как полный идиотизм).
Я сейчас выполняю программу пошагово, раставляю OutputDebugString() (совет из статьи - новое для меня), в итоге ошибка смещается (я пока в процессе анализа и разглядывания процесса с параллельным прочтением статьи).

О! Дочитал до этого момента:

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


Вообщем, проблема с динамическими массивами...
Автор: V1s1ter
Дата сообщения: 14.04.2009 17:19
Kursist
Пример

Код:
var
A: array of integer;
B: array of integer;
begin
SetLength(B, 10);
for i := 1 to 10 A[i] := i;
Автор: xXxVov4ikxXx
Дата сообщения: 15.04.2009 17:14
http://keep4u.ru/full/2009/04/15/3cebd2df87a6dac191511af9d6680ace/jpg
Нужна ваша помощь - есть игра, в которой ведется учет ходов, нужно чтобы в richtext отображался последний ход. Как видно на картинке - отображается последняя пустая строка, подскажите как ее убрать или поднять ползунок на позицию вверх... Буду очень признателен. Щас использую: SendMessage(RichText.Handle, EM_LINESCROLL, 1, 0)
Автор: greenpc
Дата сообщения: 16.04.2009 06:55
xXxVov4ikxXx

Цитата:
подскажите как ее убрать

удалить последние #13#10 (Trim('text '))

Цитата:
поднять ползунок на позицию вверх

на строку

Код: with Richedit1 do begin
selstart := perform( EM_LINEINDEX, <строка>, 0 );
perform( EM_SCROLLCARET, 0, 0 );
end;
Автор: Mandor Sawall
Дата сообщения: 16.04.2009 08:10
xXxVov4ikxXx
А как именно добавляете строку в RichText?
Автор: xXxVov4ikxXx
Дата сообщения: 16.04.2009 11:01
RichEdit.Lines.Add('blabla');
Автор: greenpc
Дата сообщения: 16.04.2009 11:13
xXxVov4ikxXx
var
tmpstr : string;
begin
tmpstr:=Trim(RichEdit.Lines.text)+#13#10+'blabla';
RichEdit.Lines.text :=tmpstr;
Автор: xXxVov4ikxXx
Дата сообщения: 16.04.2009 12:13
А можно это же только с комментами?
Автор: Dmitriy05
Дата сообщения: 16.04.2009 12:21
Дано: Программа написанная на Delphi 7 с единственной формой которая при старте имеет WindowState:= wsMaximized.

При восстановлении формы (дабл клик на заголовок приложения или нажатия кнопки в системном меню) получаеться что компоненты формы "обрезаються". Для формы были установлены MinHeight/Minwidth.

Новая проблема: После восстановления все компоненты видны, но часть формы вылезает за правую границу экрана. Возникла мысль - отловить событие restore и сделать так чтобы форма становилась в центр экрана.

Найдя на http://www.delphisources.ru/pages/faq/base/min_restore_form.html нечто похожее и изменив код получил следующее: (Constraints при этом нулевые)


Код:
procedure TMainForm.WMSyscommand(var msg: TWmSysCommand);
begin
if (msg.CmdType and $FFF0) = SC_RESTORE then begin
height:=450;
width:=900;
position:=poscreencenter;
windowstate:=wsnormal;
end
else
inherited
end;
Автор: greenpc
Дата сообщения: 16.04.2009 12:26
xXxVov4ikxXx
пожалуйста
RichEdit.Lines.text := // присвоили значение всего текста
Trim(RichEdit.Lines.text)+ // удалили все нечитаемые символы в начале и конце текста
#13#10+ // добавили перевод строки
'blabla' // добавили наш текст

Dmitriy05
а что мешает сразу в дизайнере присвоить форме
position св-во poScreenCenter
Автор: xXxVov4ikxXx
Дата сообщения: 16.04.2009 12:35
greenpc, не пашет, по крайней мере так как надо.
Вот как у меня устроен вывод:
Main.History_text.Paragraph.Alignment:=taCenter; //виведемо початковий напис в історію
Main.History_text.SelAttributes.Color:=clNavy;
// tempstr:=Trim(Main.History_text.Lines.text)+#13#10+'Початок гри';
// Main.History_text.Lines.text := tempstr;
Main.History_text.Lines.Add('Початок гри');
Main.History_text.Paragraph.Alignment:=taLeftJustify;

Main.History_text.SelAttributes.Color:=clGreen; //вивід ходу гравця в історію
case rezhym of
1: Main.History_text.Lines.Add('Хід '+IntToStr(n_hodu)+', гравець взяв '+IntToStr(n_spi4)+' сірників з '+IntToStr(n_ku4)+' кучки');
2: Main.History_text.Lines.Add('Хід '+IntToStr(n_hodu)+', гравець взяв '+IntToStr(n_spi4)+' сірників з '+IntToStr(n_ku4)+' кучки');
4: If player=1 then Main.History_text.Lines.Add('Хід '+IntToStr(n_hodu)+', гравець 1 взяв '+IntToStr(n_spi4)+' сірників з '+IntToStr(n_ku4)+' кучки')
else begin
Main.History_text.SelAttributes.Color:=clRed;
Main.History_text.Lines.Add('Хід '+IntToStr(n_hodu)+', гравець 2 взяв '+IntToStr(n_spi4)+' сірників з '+IntToStr(n_ku4)+' кучки');
end;
end;
//tempstr:=Trim(Main.History_text.Lines.text)+#13#10+'Хід '+IntToStr(n_hodu)+', гравець взяв '+IntToStr(n_spi4)+' сірників з '+IntToStr(n_ku4)+' кучки';
//Main.History_text.Lines.text := tempstr;
SendMessage(Main.History_text.Handle, EM_LINESCROLL, 1, 0);

Main.History_text.SelAttributes.Color:=clRed; //хід компа (в першому режимі)
// tempstr:=Trim(Main.History_text.Lines.text)+#13#10+'Початок гри';
// Main.History_text.Lines.text := tempstr;
Main.History_text.Lines.Add('Хід '+IntToStr(n_hodu)+', комп''ютер взяв '+IntToStr(n_spi4)+' сірників з '+IntToStr(n_ku4)+' кучки');

http://keep4u.ru/full/2009/04/16/f6a42a2b55e19b43c6180f528da0ac64/jpg
После того, как я применил ваш способ у меня получилось то, что на скрине + вобще не пашет ползунок.
Автор: greenpc
Дата сообщения: 16.04.2009 12:58
xXxVov4ikxXx
а так

Код: with Main.History_text do
begin
SelStart := Length(Trim(Text));
Perform(EM_SCROLLCARET, 0, 0);
if CanFocus then SetFocus;
end;
Автор: xXxVov4ikxXx
Дата сообщения: 16.04.2009 13:08
Тогда прокрутка не пашет и цветом не выделяет.
Автор: greenpc
Дата сообщения: 16.04.2009 13:18
xXxVov4ikxXx
у меня все ок

Код: var
i: Integer;
begin
for i := 1 to 20 do begin
if i mod 2 = 0 then Main.History_text.SelAttributes.Color := clRed
else Main.History_text.SelAttributes.Color := clGreen;
Main.History_text.Lines.Add(IntToStr(i));
end; // for
with Main.History_text do begin
SelStart := Length(Trim(Text));
Perform(EM_SCROLLCARET, 0, 0);
if CanFocus then SetFocus;
end;
end;
Автор: Dmitriy05
Дата сообщения: 16.04.2009 13:40
greenpc
Поставил poScreenCenter (+ убрал обработку Sc_Restore)
Но после восстановления форма почему-то занимает позицию poDesigned.
Может глюк винды ?

XP Pro Sp 2
Автор: xXxVov4ikxXx
Дата сообщения: 16.04.2009 13:46
Main.History_text.Paragraph.Alignment:=taCenter; //&#226;&#232;&#226;&#229;&#228;&#229;&#236;&#238; &#237;&#224;&#239;&#232;&#241; &#226; &#179;&#241;&#242;&#238;&#240;&#179;&#254;
Main.History_text.SelAttributes.Color:=clNavy;
Main.History_text.Lines.Add('&#207;&#238;&#247;&#224;&#242;&#238;&#234; &#227;&#240;&#232;');
Main.History_text.Paragraph.Alignment:=taLeftJustify;
with Main.History_text do
begin
SelStart := Length(Trim(Text));
Perform(EM_SCROLLCARET, 0, 0);
if CanFocus then SetFocus;
end;

Main.History_text.SelAttributes.Color:=clGreen; //&#226;&#232;&#226;&#179;&#228; &#245;&#238;&#228;&#243; &#226; &#179;&#241;&#242;&#238;&#240;&#179;&#254;
case rezhym of
1: Main.History_text.Lines.Add('&#213;&#179;&#228; '+IntToStr(n_hodu)+', &#227;&#240;&#224;&#226;&#229;&#246;&#252; &#226;&#231;&#255;&#226; '+IntToStr(n_spi4)+' &#241;&#179;&#240;&#237;&#232;&#234;&#179;&#226; &#231; '+IntToStr(n_ku4)+' &#234;&#243;&#247;&#234;&#232;');
2: Main.History_text.Lines.Add('&#213;&#179;&#228; '+IntToStr(n_hodu)+', &#227;&#240;&#224;&#226;&#229;&#246;&#252; &#226;&#231;&#255;&#226; '+IntToStr(n_spi4)+' &#241;&#179;&#240;&#237;&#232;&#234;&#179;&#226; &#231; '+IntToStr(n_ku4)+' &#234;&#243;&#247;&#234;&#232;');
4: If player=1 then Main.History_text.Lines.Add('&#213;&#179;&#228; '+IntToStr(n_hodu)+', &#227;&#240;&#224;&#226;&#229;&#246;&#252; 1 &#226;&#231;&#255;&#226; '+IntToStr(n_spi4)+' &#241;&#179;&#240;&#237;&#232;&#234;&#179;&#226; &#231; '+IntToStr(n_ku4)+' &#234;&#243;&#247;&#234;&#232;')
else begin
Main.History_text.SelAttributes.Color:=clRed;
Main.History_text.Lines.Add('&#213;&#179;&#228; '+IntToStr(n_hodu)+', &#227;&#240;&#224;&#226;&#229;&#246;&#252; 2 &#226;&#231;&#255;&#226; '+IntToStr(n_spi4)+' &#241;&#179;&#240;&#237;&#232;&#234;&#179;&#226; &#231; '+IntToStr(n_ku4)+' &#234;&#243;&#247;&#234;&#232;');
end;
end;
with Main.History_text do
begin
SelStart := Length(Trim(Text));
Perform(EM_SCROLLCARET, 0, 0);
if CanFocus then SetFocus;
end;

Main.History_text.SelAttributes.Color:=clRed;
Main.History_text.Lines.Add('&#213;&#179;&#228; '+IntToStr(n_hodu)+', &#234;&#238;&#236;&#239;''&#254;&#242;&#229;&#240; &#226;&#231;&#255;&#226; '+IntToStr(n_spi4)+' &#241;&#179;&#240;&#237;&#232;&#234;&#179;&#226; &#231; '+IntToStr(n_ku4)+' &#234;&#243;&#247;&#234;&#232;');
with Main.History_text do
begin
SelStart := Length(Trim(Text));
Perform(EM_SCROLLCARET, 0, 0);
if CanFocus then SetFocus;
end;

Если вот так записано, то:

1) цветом выделяется токо первая строка
2) при выводе хода что с командой, что без - пустая строка в конце остается, а когда кликаешь на прокрутку, тогда уже курсор поднимается и пустая строка опускается...
3) проблему с прокруткой решил, я просто забыл активировать ричедит...
Автор: Mandor Sawall
Дата сообщения: 16.04.2009 14:08
xXxVov4ikxXx
Добавляйте строку так:
1. Перемещайте курсор в конце текста:
Код: with Main.History_text do
begin
SelStart := Length(Text);
SelLength := 0;
end;
Автор: xXxVov4ikxXx
Дата сообщения: 16.04.2009 15:49
Пасиб огромное - помогло....

Страницы: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667

Предыдущая тема: Глобальные переменные в разных формах с++ builder 'a.


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.