Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Delphi (все версии) - часть 4

Модерирует : ShIvADeSt

ShIvADeSt (28-06-2009 02:10): Продолжение в http://forum.ru-board.com/topic.cgi?forum=33&topic=10477  Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

   

Kursist



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Извиняюсь, что перебиваю тему.
Возникла проблема. Delphi2007/Vista
В программе несколько форм. Неожиданно перестала запускаться одна из форм, на ней  
несколько стандартных компонентов для ввода данных. На этой форме нет процедуры создания, но именно при создании приложения, компилятор проходит создание предыдущих форм, а на этой вылетает ошибка. В ассемблере не разбираюсь, поэтому информацию о состоянии ЦПУ на момент ошибки понять не могу.
Какие могут быть идеи?
 

Всего записей: 137 | Зарегистр. 12-07-2004 | Отправлено: 20:11 13-04-2009
Frodo_Torbins

Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Kursist
Как минимум нужно знать сообщение об ошибке, чтобы появились идеи. А вообще попробуйте с EurekaLog свою программу погонять.

Всего записей: 2319 | Зарегистр. 24-05-2007 | Отправлено: 20:39 13-04-2009
Kursist



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Project ..exe faulted with message 'access violation at 0x... write of address... Process stoped. Use Step or Run to continue...  
 
Скачал и проинсталлировал триал EurekaLog. Странное дело! Когда его активизировал - программа запустилась, нужное мне окно стало открываться, но стала возникать ошибка на совсем другом месте (на задании размера динамическому массиву, чего до этого не было!), в совсем другой форме и в другом объекте, который не связан с предыдущей формой... шаманство какое-то, но разобраться хочется! Когда EurekaLog деактивируешь, то приложение не запускается - стопорится на том же месте, где и раньше.
 
 

Всего записей: 137 | Зарегистр. 12-07-2004 | Отправлено: 21:44 13-04-2009 | Исправлено: Kursist, 21:47 13-04-2009
Frodo_Torbins

Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Kursist
Внимательно просмотрите все свои операции с памятью, похоже вы где то затираете лишнее. Еще "Range checking" включите.

Всего записей: 2319 | Зарегистр. 24-05-2007 | Отправлено: 21:52 13-04-2009
Kursist



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
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]
 
 
Предположительно ошибка "плавающая" - вспомнил, что в одной из старых версий программы тоже вдруг перестала запускаться одна из форм, только на тот момент она оказалась "лишней"...вообщем, чувствую, надо будет долго-долго искать...

Всего записей: 137 | Зарегистр. 12-07-2004 | Отправлено: 23:05 13-04-2009 | Исправлено: Kursist, 23:20 13-04-2009
Frodo_Torbins

Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Kursist
Похоже вы все же где то трете память. До добавления EurekaLog затиралась память необходимая для создания формы, теперь на этом месте self.FLoadedSPT. Возможно на self.FLoadedSPT стоит поставить бряк на память, чтобы узнать откуда трется. Подробнее: Обработка ошибок.

Всего записей: 2319 | Зарегистр. 24-05-2007 | Отправлено: 23:55 13-04-2009
Kursist



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Спасибо 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); - может это создавать утечку?

Всего записей: 137 | Зарегистр. 12-07-2004 | Отправлено: 00:54 14-04-2009
ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
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;  

Не знаю, но может поможет. Ты пытаешься читать из потока несколько раз, при этом не проверяя конец ли потока или нет. Лучше всего получить размер потока и смотреть не конец ли.

----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 02:18 14-04-2009
V1s1ter



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Kursist

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

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

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

Это утечку создавать не может, поскольку Ты говориш "выдели мне аж ноль байт памяти для FTexRegionArr". К стати если эта строка у тебя в XXXX.Create, a FTexRegionArr это переменная класса XXXX, то данная строка лишняя, посколику все переменные объекта при создании устанавливаются в ноль или его аналоги.

Всего записей: 948 | Зарегистр. 06-02-2007 | Отправлено: 11:42 14-04-2009
Kursist



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
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, но мне показалось, что такой код с массивами более симпатичен/проще/компактнее, но вот, напоролся на грабли с утечкой памяти.

Всего записей: 137 | Зарегистр. 12-07-2004 | Отправлено: 12:04 14-04-2009
V1s1ter



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Kursist

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

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

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

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

Всего записей: 948 | Зарегистр. 06-02-2007 | Отправлено: 12:14 14-04-2009
Kursist



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
V1s1ter

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

ОК. Понял.
 
Добавлено:
V1s1ter

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

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

 мне многое прояснило
Цитата:
...где то трете память  
- я назвал "утечкой", тем более, что EurekaLog показал Memory Leak.  
 
На данном этапе стали сыпаться ошибки за ошибкой.
Сейчас проверяю все свои SetLength(), GetMem() и FreeMem()

Всего записей: 137 | Зарегистр. 12-07-2004 | Отправлено: 12:16 14-04-2009
Frodo_Torbins

Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Kursist
Утечка это немного другое. Например вы создаете объект, а потом ссылка на него где то теряется. Он, не удаленный, так и остается висеть в памяти мертвым грузом - это утечка. В вашем случае похоже утечки являются не причиной, а следствием (ну и плюс вылеты).
P.S. А статью я еще сам не дочитал, но уже сейчас вижу, сколько раньше делал ошибок

Всего записей: 2319 | Зарегистр. 24-05-2007 | Отправлено: 15:10 14-04-2009 | Исправлено: Frodo_Torbins, 15:14 14-04-2009
Kursist



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Frodo_Torbins
Можете мне объяснить, как вообще происходит "затирание памяти". Что это такое? Как такое возможно, что происходит смещение ошибки (выглядит это как полный идиотизм).
Я сейчас выполняю программу пошагово, раставляю OutputDebugString() (совет из статьи - новое для меня), в итоге ошибка смещается (я пока в процессе анализа и разглядывания процесса с параллельным прочтением статьи).  
 
О! Дочитал до этого момента:

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

 
Вообщем, проблема с динамическими массивами...

Всего записей: 137 | Зарегистр. 12-07-2004 | Отправлено: 17:40 14-04-2009 | Исправлено: Kursist, 18:16 14-04-2009
V1s1ter



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Kursist
Пример

Код:
 
var
  A: array of integer;
  B: array of integer;
begin
  SetLength(B, 10);
  for i := 1 to 10 A[i] := i;
 
 
Допустим, поскольку A не инициализировано (под него не выделена память), то оно указывает на случайный участок памяти. Для примера пусть A erfpsdftn на серидину масива В. Тогда в wfrkt перепишится половина масива В и еще около 20 байт за этим масивом. В результате ошибка выскочит при обработке масива В.  
Другой вариант, если предположить что A указывала на участок памяти с кодом процедуры X, то ошибка появится при вызове процедуры X после того как выполнится цикл, а до цикла вызов процедуры Х будет проходить коректно.
 
Далее, предположим что при запуске память распределяется одинаково, если код програмы не меннялся. Тогда участок кода приведенного выше будет таким

Код:
 
                        var      
DE3287CA             A: array of integer;
FFA9352D             B: array of integer;
34923654
 
 
То есть A указывает на часток памяти с адресом DE3287CA и при выполнении цикла портит именно его.
Теперь добавим одну переменную

Код:
 
                        var      
DE3287CA             R: integer;
FFA9352D             A: array of integer;  
34923654             B: array of integer;
 
 
Перменная R заняла место A, а сама переменная A указывает теперь на совсеем другой участок памяти и будет портить именно его.  
Для лучшего понимания рекомендую начинать с простого паскаля, тема работа с указателями.

Всего записей: 948 | Зарегистр. 06-02-2007 | Отправлено: 18:19 14-04-2009
xXxVov4ikxXx



Junior Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
http://keep4u.ru/full/2009/04/15/3cebd2df87a6dac191511af9d6680ace/jpg
Нужна ваша помощь - есть игра, в которой ведется учет ходов, нужно чтобы в richtext отображался последний ход. Как видно на картинке - отображается последняя пустая строка, подскажите как ее убрать или поднять ползунок на позицию вверх... Буду очень признателен. Щас использую: SendMessage(RichText.Handle, EM_LINESCROLL, 1, 0)

Всего записей: 64 | Зарегистр. 26-01-2009 | Отправлено: 18:14 15-04-2009
greenpc

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
xXxVov4ikxXx

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

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

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

на строку

Код:
with Richedit1 do begin
     selstart := perform( EM_LINEINDEX, <строка>, 0 );
     perform( EM_SCROLLCARET, 0, 0 );
end;
 

Всего записей: 401 | Зарегистр. 18-04-2003 | Отправлено: 07:55 16-04-2009 | Исправлено: greenpc, 08:00 16-04-2009
Mandor Sawall

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
xXxVov4ikxXx
А как именно добавляете строку в RichText?

Всего записей: 119 | Зарегистр. 20-03-2003 | Отправлено: 09:10 16-04-2009
xXxVov4ikxXx



Junior Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
RichEdit.Lines.Add('blabla');

Всего записей: 64 | Зарегистр. 26-01-2009 | Отправлено: 12:01 16-04-2009 | Исправлено: xXxVov4ikxXx, 12:02 16-04-2009
greenpc

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
xXxVov4ikxXx
var  
tmpstr : string;
begin
tmpstr:=Trim(RichEdit.Lines.text)+#13#10+'blabla';
RichEdit.Lines.text :=tmpstr;

Всего записей: 401 | Зарегистр. 18-04-2003 | Отправлено: 12:13 16-04-2009 | Исправлено: greenpc, 12:28 16-04-2009
   

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Delphi (все версии) - часть 4
ShIvADeSt (28-06-2009 02:10): Продолжение в http://forum.ru-board.com/topic.cgi?forum=33&topic=10477


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru