Меню

Procedure tform1 button1click sender tobject ошибка

xamelione25

-4 / 5 / 2

Регистрация: 04.02.2013

Сообщений: 1,653

1

02.02.2014, 14:08. Показов 23465. Ответов 11

Метки нет (Все метки)


Delphi
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
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;
type
  TForm1 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
PROCEDURE TForm1.Button1Click(Sender: TObject);
Var s:Real
    i:Integer;
begin
S:=0;
i:=1;
while i<=50 do
   begin
   S:=S+1/n;
   n:=n+1;
   End;
label1.Caption:='S='+FloatToStr(s);
End;
End;
implementation
{$R *.dfm}
end.

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



U_Dimas

fatal error

136 / 128 / 29

Регистрация: 10.04.2012

Сообщений: 357

02.02.2014, 14:23

2

Как то -так

Delphi
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
unit Unit1;
 interface
 uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;
 type
 TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
 private
 { Private declarations }
 public
 { Public declarations }
 end;
 var
 Form1: TForm1;
 implementation
 {$R *.dfm}
 
 PROCEDURE TForm1.Button1Click(Sender: TObject);
 Var
 s:Real;
 i,n :Integer;
 begin
 S:=0;
 i:=1;
 while i < =50 do
 begin
 S:=S+1 / n;
 n:=n+1;
 End;
 label1.Caption:='S='+FloatToStr(s);
 End;

Что такое n ? Условие while никогда не наступит потому что i не меняется



1



Супер-модератор

Эксперт Pascal/DelphiАвтор FAQ

32444 / 20939 / 8104

Регистрация: 22.10.2011

Сообщений: 36,202

Записей в блоге: 7

02.02.2014, 14:24

3

Цитата
Сообщение от xamelione25
Посмотреть сообщение

выдает ошибку

Ты забыл слово Implementation перед началом реализации методов…



1



-4 / 5 / 2

Регистрация: 04.02.2013

Сообщений: 1,653

02.02.2014, 14:30

 [ТС]

4

а теперь ошибку выдает в предпоследней строке



0



fatal error

136 / 128 / 29

Регистрация: 10.04.2012

Сообщений: 357

02.02.2014, 14:32

5

Какую ? label1 не найден ?



1



Супер-модератор

Эксперт Pascal/DelphiАвтор FAQ

32444 / 20939 / 8104

Регистрация: 22.10.2011

Сообщений: 36,202

Записей в блоге: 7

02.02.2014, 14:33

6

Так надо было просто 29 и 30 строку (изначального кода) взять и перенести наверх, добавить после 14-ой строки…

Добавлено через 37 секунд

Цитата
Сообщение от U_Dimas
Посмотреть сообщение

Какую ? label1 не найден ?

В код из первого поста посмотри, увидишь, какую…



1



-4 / 5 / 2

Регистрация: 04.02.2013

Сообщений: 1,653

02.02.2014, 14:38

 [ТС]

7



0



fatal error

136 / 128 / 29

Регистрация: 10.04.2012

Сообщений: 357

02.02.2014, 14:40

8

Лучший ответ Сообщение было отмечено xamelione25 как решение

Решение

label1 добавте на форму



1



-4 / 5 / 2

Регистрация: 04.02.2013

Сообщений: 1,653

02.02.2014, 14:44

 [ТС]

9

поясните, я просто только начинаю дружити с делфи (ничёго незрозумиваю), 1 лаба



0



fatal error

136 / 128 / 29

Регистрация: 10.04.2012

Сообщений: 357

02.02.2014, 14:45

10

Лучший ответ Сообщение было отмечено xamelione25 как решение

Решение

Вкладка Standart в ней имеется компонент label, щелкаете на нее она появляется на форме



1



-4 / 5 / 2

Регистрация: 04.02.2013

Сообщений: 1,653

02.02.2014, 14:55

 [ТС]

11

http://pixs.ru/showimage/Bezim… 714291.png

поясните а что это за окно??
как я понял то это программа успешно выполнена???
ну а тогда почему нет ответа на задание вычислить сумму S=1+1/2+1/3+…+1/50



0



fatal error

136 / 128 / 29

Регистрация: 10.04.2012

Сообщений: 357

02.02.2014, 15:00

12

Это окно вашей программы — лишник label- ы можно убрать, выделяете и жмете кнопку delete
Так же не видно компонента button — так же в Standart
Код не верный, вы проверяете i<=50 но никаких манипуляций с переменной не производите



1



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

02.02.2014, 15:00

Помогаю со студенческими работами здесь

Показывает ошибку в procedure Form2Button1Click(Sender: TObject);
unit Unit2;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,…

Выдаёт ошибку на процедуре procedure FromImage3Click(Sender: TObject);, говорит, что такой не может найти
nit Unit2;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,…

Код прописан правильно, но всё равно ошибка выбивается в строке procedure TForm1.FormCloseSender:(TObject; var Action: TCloseAction);??? Что делать??
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,…

Как в Delphi 7 вызвать TForm1.N1Click(Sender: TObject)?
как в Delphi 7 вызвать TForm1.N1Click(Sender: TObject);

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:

12

Модераторы:Duncon, Naeel Maqsudov, Игорь Акопян, Хыиуду

Twins

Сообщения:2
Зарегистрирован:27 ноя 2004, 11:36
Откуда:Луганск

Help me.
Глупость но факт.
В Delphi 7 не могу открыть форму2 из формы1

Создаю Form1
Создаю Button1 в Form1
Компилирую
Создаю Form2

Вешаю на Button1 в Form1
procedure TForm1.Button1Click(Sender: TObject);
begin
form2.ShowModal;
end;

Компилирую
Пишет
(Ошибка) Unit.pas(35): Undeclared identifier: «form2»
(Фатальная ошибка) Proect1.dpr6: Cold not compile used unit ‘Unit1.pas’

Дальше — мрак. Тишина

Заранее спасибо за помощь.
Чайник (надеюсь не на долго)

Аватара пользователя

AiK

Сообщения:2271
Зарегистрирован:13 фев 2004, 18:14
Откуда:СПб
Контактная информация:

27 ноя 2004, 17:22

Twins, во-первых, ошибка из-за того, что в первом модуле переменная form2 не объявлена.
Во-вторых, прежде чем показывать форму, её создать нужно.

Т.е. тебе нужно что-то вроде этого:
В первом модуле:
Uses Unit2.pas;

procedure TForm1.Button1Click(Sender: TObject);
var form2: TForm2;
begin
form2:=TForm2.Create(Form1);
form2.ShowModal;
end;

Даже самый дурацкий замысел можно воплотить мастерски

Twins

Сообщения:2
Зарегистрирован:27 ноя 2004, 11:36
Откуда:Луганск

27 ноя 2004, 22:22

AiK

Большое человеческое спасибо.
Хватило
В первом модуле:
Uses Unit2;

Еще Чайник, но уже меньше.
Twins

Лопата:)

Сообщения:4
Зарегистрирован:17 дек 2013, 09:32

17 дек 2013, 09:36

AiK писал(а):Twins,
procedure TForm1.Button1Click(Sender: TObject);

вот на этой строчке он меня и мучает:
[Error] Unit1.pas(36): Statement expected but ‘PROCEDURE’ found
что делать??

Аватара пользователя

somewhere

Сообщения:1837
Зарегистрирован:31 авг 2006, 17:14
Откуда:71 RUS
Контактная информация:

17 дек 2013, 10:56

что делать??

Скорее всего процедура не описана в классе TForm1

It’s a long way to the top if you wanna rock’n’roll

Лопата:)

Сообщения:4
Зарегистрирован:17 дек 2013, 09:32

17 дек 2013, 11:05

А можно подробнее написать, как это сделать, а то я совсем не понимаю :)

Аватара пользователя

somewhere

Сообщения:1837
Зарегистрирован:31 авг 2006, 17:14
Откуда:71 RUS
Контактная информация:

17 дек 2013, 11:08

В описателе класса добавить
procedure Button1Click(Sender: TObject);

кнопке Button1 событию OnClick присвоить обработчик Button1Click

It’s a long way to the top if you wanna rock’n’roll

Лопата:)

Сообщения:4
Зарегистрирован:17 дек 2013, 09:32

17 дек 2013, 11:25

type
TForm1 = class(TForm)
Button1Click(Sender: TObject);
теперь он просит заменить ( на :

заменила
теперь опять докопался до процедуры
[Error] Unit1.pas(50): Statement expected but ‘PROCEDURE’ found

Аватара пользователя

somewhere

Сообщения:1837
Зарегистрирован:31 авг 2006, 17:14
Откуда:71 RUS
Контактная информация:

17 дек 2013, 11:40

Дальше ничего не могу сказать — нет полного кода

It’s a long way to the top if you wanna rock’n’roll

Лопата:)

Сообщения:4
Зарегистрирован:17 дек 2013, 09:32

17 дек 2013, 14:45

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
lbl1: TLabel;
edt1: TEdit;
procedure button1Click(Sender: TObject);

private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm;
Form2: TForm;
Edit1: TEdit;
implementation
{$R *.dfm}
begin
procedure button1Click(Sender: TObject);
begin
form2.Show;
end;

end.

Ошибки — неизбежное зло программирования. Видимо пока трудно даже представить средство с помощью которого можно избавится от них. Человеку, которые выдумает это чудодейственное лекарство, благодарные потомки-программисты, несомненно, воздвигнут памятник. Пока же остается лишь заниматься обычным делом: ловлей багов.
«Нарушение Доступа» — фраза, которую пользователи видят, когда приложение делает попытки обратиться к памяти, которая не обозначена для их использования — и как следствие происходит сбой в работе программы:

Access violation at address

in module .
Read of address
Ситуация при которой Windows давала бы полную свободу программам — записывай данные куда хочешь, скорее всего бы привела к разноголосице программ и полной потери управления над компьютером. Но этого не происходит — Windows стоит на страже «границ памяти» и отслеживает недопустимые операции. Если сама она справиться с ними не в силах — происходит запуск утилиты Dr. Watson, которая записывает данные о возникшей ошибки, а сама программа закрывается.
Известно что, при программирование, особенно крупных программных продуктов, уследить за всеми процессами в коде невозможно, да и нет необходимости. Использование сторонних компонентов и библиотек только усложняет дело. Именно поэтому программисты Delphi, порой и сталкиваются со «своенравными» программами, которые то и дело норовят «сбросить пользователя». Итак, давайте рассмотрим некоторые вопросы, связанные с корректной среды программирования, так и непосредственно проблемы написания кода, которые ведут к возникновению ошибок типа «ошибка доступа» (AVS) и очертим наиболее известные пути их исправления.
Мы можем поделить AVS, с которыми сталкиваются при разработке в Delphi на два основных типах: ошибки при выполнения и некорректная разработка проекта, что вызывает ошибки при работе программы.
Ошибки возникают при старте и закрытии Delphi или формировании проекта. Причиной могут являться сбои в «железе» компьютера.
Эти ошибки могут быть вызваны различными источниками, включая систему BIOS, операционную систему или аппаратные подпрограммы драйверов. Некоторые видео-, звуковые или сетевые платы могут фактически вызывать подобного рода ошибки в Delphi. Для решения подобных аппаратных проблем можно предпринять последовательность неких «стандартных» ходов:
проверить, что не имеется никаких конфликтов между установленными устройствами, устранить обнаруженные конфликты;
попробовать слегка уменьшить «аппетита» видеодрайвера — поставить меньшее разрешение;
в случае если у вас двухпроцесорная система обеспечить равное изменение шага для каждого процессора;
И в конце концов просто попытаться заменить драйвера на более свежие.

Но помимо чисто железных проблем — большую головную боль могут вызвать ошибки в работе программного обеспечения. Особенно это касается непосредственно операционной системы. Зачастую Windows терпит крах спонтанно. Вот рекомендации которые помогут вам создать более устойчивую среду программирования:
Хотя Windows 9X популярная система, разработку лучше проводить в Windows NT или Windows 2000 — это более устойчивые операционные системы. Естественно при переходе на них придется отказаться от некоторых благ семейства Windows 95/98/Me — в частности не все программы адоптированы для Windows NT/2000. Зато вы получите более надежную и стабильную систему.
Не забывайте о том, как важно всегда иметь под рукой свежие версии компонентов для Delphi и дополнительных библиотек. В отличие от Windows создатели данных пакетов стараются от версии к версии уменьшать количество ошибок.
Следите за тем, что бы устанавливаемые компоненты были предназначены непосредственно для вашей версии Delphi. Попробуйте деинсталлировать чужеродные компоненты один за другим (или пакет за пакетом) пока проблема не будет устранена.
Контролируйте все программные продукты установленные на вашей машине и деинсталлируйте те из них, которые сбоят. Фаворитами AV среди них являются шароварные утилиты и программы и бета версии программных продуктов.
Все вышеперечисленное в основном не касалось самого процесса программирования и в малой степени зависит от разработчика. Теперь же обратимся к теме, как не допустить при разработки программного продукта ситуации при которой, он сам будет являться причиной ошибки.
Вы могли бы рассмотреть компилирование вашего приложения с директивой {$D}, данная директива компилятора может создавать файлы карты (файлы с расширением map, которые можно найти в том же каталоге, что и файлы проекта), которые могут послужить большой справкой в локализации источника подобных ошибок. Для лучшего «контроля» за своим приложением, компилируйте его с директивой {$D}. Таким образом, вы заставите Delphi генерировать информацию для отладки, которая может послужить подспорьем при выявление возникающих ошибок.
Следующая позиция в Project Options — Linker & Compiler позволяет вам, определить все для последующей отладки. Лучше всего, если помимо самого выполняемого кода будет доступна и отладочная информация — это поможет при поиске ошибок. Отладочная информация увеличивает размер файла и занимает дополнительную память при компилировании программ, но непосредственно на размер или быстродействие выполняемой программы не влияет. Включение опций отладочной информации и файла карты дают детальную информацию только, если вы компилируете программу с директивой {$D+}.
Эта информация состоит из таблицы номеров строк для каждой процедуры, которая отображает адреса объектных кодов в номера строк исходного текста. Директива $D обычно используется совместно с другой директивой — $L, что позволяет или запрещает генерацию информации о локальных символах для отладки.
Таким образом вы без труда сможете найти точный адрес той подпрограммы, которая была ответственна за ошибку. Одна из наиболее общих причин ошибок выполнения — использование объекта, который еще не был создан. Если второй адрес при выдачи ошибки — FFFFFFF (или 0000000) Вы можете почти утверждать, что было обращение к объекту, который еще не был создан. Например, вызов метода формы, которая не была создана.

procedure TfrMain.OnCreate(Sender: TObject);
 var BadForm: TBadForm;
 begin
   BadForm.Refresh; // причина  ошибки
 end;
 

Попытаемся разобратся в этой ситуации. Предположим, что BadForm есть в списке «Available forms » в окне Project Options|Forms. В этом списке находятся формы, которые должны быть созданы и уничтожены вручную. В коде выше происходит вызов метода Refresh формы BadForm, что вызывает нарушение доступа, так как форма еще не была создана, т.е. для объекта формы не было выделено памяти.
Если вы установите «Stop on Delphi Exceptions » в Language Exceptions tab в окне Debugger Options, возможно возникновения сообщение об ошибке, которое покажет, что произошло ошибка типа EACCESSVIOLATION. EACCESSVIOLATION — класс исключение для недопустимых ошибок доступа к памяти. Вы будете видеть это сообщение при разработке вашего приложения, т.е. при работе приложения, которое было запущено из среды Delphi.
Следующее окно сообщения будет видеть пользователь — и программа будет закрыта при совершение недопустимой операции:

 Access violation at address 0043F193
 in module 'Project1.exe'
 Read of address 000000.
 

Первое шестнадцатиричное число (‘0043F193’) — адрес ошибки во время выполнения программы в программе. Выберите, опцию меню ‘Search|Find Error’, введите адрес, в котором произошла ошибка (‘0043F193’) в диалоге и нажмите OK. Теперь Delphi перетранслирует ваш проект и покажет вам, строку исходного текста, где произошла ошибка во время выполнения программы, то есть BadForm.Refresh.
Естественно, что списка наиболее общих причин ошибок, вызывающих аварийное завершение работы программы, написанной в Delphi в чистом виде нет. Есть несколько общих «узких мест» в коде и структуре программы, когда подобная ошибка может произойти. Перечислим наиболее распространенные.

Недопустимый параметр API

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

Уничтожение исключения

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

 Zero:=0;
 try
    dummy:= 10 / Zero;
 except on E: EZeroDivide do
    MessageDlg('Can not divide by zero!', mtError, [mbOK], 0);
    E.free. // причина ошибки
 end;
 

Индексация пустой строки
Пустая строка не имеет никаких достоверных данных. Следовательно, попытка индексировать пустую строку — подобно попытке обратиться к нулю, что приведет также к ошибке:

 var s: string;
 begin
    s:='';
    s[1]:='a'; // причина ошибки
 end;
 

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

 procedure TForm1.Button1Click(Sender: TObject);
 var
   p1 : pointer;
   p2 : pointer;
 begin
   GetMem(p1, 128);
   GetMem(p2, 128);
  {эта строка может быть причиной ошибки}
   Move(p1, p2, 128);
  {данная строка корректна }
   Move(p1^, p2^, 128);
   FreeMem(p1, 128);
   FreeMem(p2, 128);
 end;
 

Вот и всё, Удачи!

Максим писал(а):Lazarus к обеим этим проблемам отношения не имеет. Это компилятор и/или отладчик.

Проверяйте с FPC версии 2.7.1 и, если воспроизведётся, пишите в багтрекер FPC.

Спасибо. Попробую сделать всё это. Хотя если бы более опытный человек это сделал, то было бы намного быстрее, т.к. никогда ни с тем, ни с другим дела не имел пока.

xdsl писал(а):По второму примеру.
Проблема, похоже не в объектах, а в использовании неинициализированных статических структур нулевой длины (sizeof возвращает 0).
Поставьте record вместо object — получите такую-же ошибку. Но достаточно завести хотя-бы одно поле в структуре, или инициализировать ее выносом в глобальную область видимости — ошибка исчезает.

>Поставьте record вместо object — получите такую-же ошибку.
Да.

>Но достаточно завести хотя-бы одно поле в структуре,
Нет, остаётся, независимо от того, это object или record

> или инициализировать ее выносом в глобальную область видимости
Когда вынес то да, исчезла, даже если не заводить поле в структуре.

Дальше ради интереса решил ещё посмотреть и получил вот что —

1. Если в этом случае к обьекту добавить конструктор, то ошибка возникает.

Код: Выделить всё
tobj=object
constructor init;
end;

var Form1: TForm1;
cc:tobj;

operator :=(cc:tobj)r:integer;

implementation  { TForm1 }    {$R *.lfm}

constructor tobj.init;
begin

end;

operator :=(cc:tobj)r:integer;
begin
r:=0;
end;

procedure TForm1.Button2Click(Sender: TObject);
var x:array of integer;
begin
cc.init;
showmessage(inttostr(cc)); //ОК, показывает ноль
setlength(x,1);
x[cc]:=10; //ошибка - "Проект вызвал класс иключения 'External: SIGSEGV'"
end;

2. Если в этом случае добавить поле к обьекту, то ошибка пропадает.

Код: Выделить всё
tobj=object
  i:integer;
constructor init;
end;

var Form1: TForm1;
cc:tobj;

operator :=(cc:tobj)r:integer;

implementation  { TForm1 }    {$R *.lfm}

constructor tobj.init;
begin
i:=10;
end;

operator :=(cc:tobj)r:integer;
begin
r:=0;
end;

procedure TForm1.Button2Click(Sender: TObject);
var x:array of integer;
begin
cc.init;
showmessage(inttostr(cc)); //ОК, показывает ноль
setlength(x,1);
x[cc]:=10; //ошибка - "Проект вызвал класс иключения 'External: SIGSEGV'"
end;

3. Если этот обьект сделать наследником другого, пустого обьекта с конструктором, то ошибка опять появляется.

Код: Выделить всё
tobj0=object
constructor init;
end;

tobj=object(tobj0)
  i:integer;
constructor init;
end;

var Form1: TForm1;
cc:tobj;

operator :=(cc:tobj)r:integer;

implementation  { TForm1 }    {$R *.lfm}

constructor tobj0.init;
begin

end;

constructor tobj.init;
begin
i:=10;
end;

operator :=(cc:tobj)r:integer;
begin
r:=0;
end;

procedure TForm1.Button2Click(Sender: TObject);
var x:array of integer;
begin
cc.init;
showmessage(inttostr(cc)); //ОК, показывает ноль
setlength(x,1);
x[cc]:=10; //ошибка - "Проект вызвал класс иключения 'External: SIGSEGV'"
end;

4. Если тогда обьекту родителю сделать какое-нибудь поле, то ошибка опять пропадает.

2001 г

Ловим баги или Почему программы допускают «недопустимые операции»

Е. Левшаков, В. Ковалев, mcsa.ru

Ошибки — неизбежное зло программирования. Видимо, пока трудно даже представить средство с помощью которого можно избавится от них. Человеку, который выдумает это чудодейственное лекарство, благодарные потомки-программисты, несомненно, воздвигнут памятник. Пока же остается лишь заниматься обычным делом: ловлей багов.

«Нарушение Доступа» — фраза, которую пользователи видят, когда приложение делает попытки обратиться к памяти, которая не обозначена для их использования — и как следствие происходит сбой в работе программы:

Access violation at address <HEX_value>
in module <Application.Exe>.
Read of address <HEX_value_2>

Ситуация, при которой Windows давала бы полную свободу программам — записывай данные куда хочешь, скорее всего бы привела к разноголосице программ и полной потери управления над компьютером. Но этого не происходит — Windows стоит на страже «границ памяти» и отслеживает недопустимые операции. Если сама она справиться с ними не в силах — происходит запуск утилиты Dr. Watson, которая записывает данные о возникшей ошибке, а сама программа закрывается.

Известно, что при программировании, особенно крупных программных продуктов, уследить за всеми процессами в коде невозможно, да и нет необходимости. Использование сторонних компонентов и библиотек только усложняет дело. Именно поэтому программисты Delphi порой и сталкиваются со «своенравными» программами, которые то и дело норовят «сбросить пользователя». Итак, давайте рассмотрим некоторые вопросы, связанные с корректной средой программирования, так и непосредственно проблемы написания кода, которые ведут к возникновению ошибок типа «ошибка доступа» (AVS) и очертим наиболее известные пути их исправления.

Мы можем поделить AVS, с которыми сталкиваются при разработке в Delphi, на два основных типах: ошибки при выполнения и некорректная разработка проекта, что вызывает ошибки при работе программы.

Ошибки возникают при старте и закрытии Delphi или формировании проекта. Причиной могут являться сбои в «железе» компьютера.

Эти ошибки могут быть вызваны различными источниками, включая систему BIOS, операционную систему или аппаратные подпрограммы драйверов. Некоторые видео-, звуковые или сетевые платы могут фактически вызывать подобного рода ошибки в Delphi. Для решения подобных аппаратных проблем можно предпринять последовательность неких «стандартных» ходов:

  • проверить, что не имеется никаких конфликтов между установленными устройствами, устранить обнаруженные конфликты;
  • попробовать слегка уменьшить «аппетиты» видеодрайвера — поставить меньшее разрешение;
  • в случае если у вас двухпроцесорная система обеспечить равное изменение шага для каждого процессора;

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

Но помимо чисто железных проблем — большую головную боль могут вызвать ошибки в работе программного обеспечения. Особенно это касается непосредственно операционной системы. Зачастую Windows терпит крах спонтанно. Вот рекомендации которые помогут вам создать более устойчивую среду программирования:

Хотя Windows 9X популярная система, разработку лучше проводить в Windows NT или Windows 2000 — это более устойчивые операционные системы. Естественно, при переходе на них придется отказаться от некоторых благ семейства Windows 95/98/Me — в частности, не все программы адаптированы для Windows NT/2000. Зато вы получите более надежную и стабильную систему.

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

Следите за тем, чтобы устанавливаемые компоненты были предназначены непосредственно для вашей версии Delphi. Попробуйте деинсталлировать чужеродные компоненты один за другим (или пакет за пакетом), пока проблема не будет устранена.

Контролируйте все программные продукты, установленные на вашей машине и деинсталлируйте те из них, которые сбоят. Фаворитами AV среди них являются шароварные утилиты и программы и бета версии программных продуктов.

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

Вы могли бы рассмотреть компилирование вашего приложения с директивой {$D}, данная директива компилятора может создавать файлы карты (файлы с расширением map, которые можно найти в том же каталоге, что и файлы проекта), которые могут послужить большой справкой в локализации источника подобных ошибок. Для лучшего «контроля» за своим приложением компилируйте его с директивой {$D}. Таким образом, вы заставите Delphi генерировать информацию для отладки, которая может послужить подспорьем при выявление возникающих ошибок.

Следующая позиция в Project Options — Linker & Compiler позволяет вам, определить все для последующей отладки. Лучше всего, если помимо самого выполняемого кода будет доступна и отладочная информация — это поможет при поиске ошибок. Отладочная информация увеличивает размер файла и занимает дополнительную память при компилировании программ, но непосредственно на размер или быстродействие выполняемой программы не влияет. Включение опций отладочной информации и файла карты дают детальную информацию только если вы компилируете программу с директивой {$D+}.

Эта информация состоит из таблицы номеров строк для каждой процедуры, которая отображает адреса объектных кодов в номера строк исходного текста. Директива $D обычно используется совместно с другой директивой — $L, что позволяет или запрещает генерацию информации о локальных символах для отладки.

Таким образом вы без труда сможете найти точный адрес той подпрограммы, которая была ответственна за ошибку. Одна из наиболее общих причин ошибок выполнения — использование объекта, который еще не был создан. Если второй адрес при выдачи ошибки — FFFFFFF (или 0000000) Вы можете почти утверждать, что было обращение к объекту, который еще не был создан. Например, вызов метода формы, которая не была создана.

procedure TfrMain.OnCreate(Sender: TObject);
 var BadForm: TBadForm;
 begin
   BadForm.Refresh; // причина  ошибки
 end;

Попытаемся разобратся в этой ситуации. Предположим, что BadForm есть в списке «Available forms» в окне Project Options|Forms. В этом списке находятся формы, которые должны быть созданы и уничтожены вручную. В коде выше происходит вызов метода Refresh формы BadForm, что вызывает нарушение доступа, так как форма еще не была создана, т.е. для объекта формы не было выделено памяти.

Если вы установите «Stop on Delphi Exceptions» в Language Exceptions tab в окне Debugger Options, возможно возникновение сообщения об ошибке, которое покажет, что произошло ошибка типа EACCESSVIOLATION. EACCESSVIOLATION — класс исключение для недопустимых ошибок доступа к памяти. Вы будете видеть это сообщение при разработке вашего приложения, т.е. при работе приложения, которое было запущено из среды Delphi.

Следующее окно сообщения будет видеть пользователь — и программа будет закрыта при совершение недопустимой операции:

 Access violation at address 0043F193
 in module 'Project1.exe'
 Read of address 000000.

Первое шестнадцатиричное число (‘0043F193’) — адрес ошибки во время выполнения программы. Выберите опцию меню ‘Search|Find Error’, введите адрес, в котором произошла ошибка (‘0043F193’) в диалоге и нажмите OK. Теперь Delphi перетранслирует ваш проект и покажет вам строку исходного текста, где произошла ошибка во время выполнения программы, то есть BadForm.Refresh.

Естественно, что списка наиболее общих причин ошибок, вызывающих аварийное завершение работы программы, написанной в Delphi, в чистом виде нет. Есть несколько общих «узких мест» в коде и структуре программы, когда подобная ошибка может произойти. Перечислим наиболее распространенные.

Недопустимый параметр API

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

Уничтожение исключения

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

 Zero:=0;
 try
    dummy:= 10 / Zero;
 except on E: EZeroDivide do
    MessageDlg('Can not divide by zero!', mtError, [mbOK], 0);
    E.free. // причина ошибки
 end;

Индексация пустой строки

Пустая строка не имеет никаких достоверных данных. Следовательно, попытка индексировать пустую строку — подобно попытке обратиться к нулю, что приведет также к ошибке:

 var s: string;
 begin
    s:='';
    s[1]:='a'; // причина ошибки
 end;

Обращение к динамической переменной

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

procedure TForm1.Button1Click(Sender: TObject);
 var
   p1 : pointer;
   p2 : pointer;
 begin
   GetMem(p1, 128);
   GetMem(p2, 128);
  {эта строка может быть причиной ошибки}
   Move(p1, p2, 128);
  {данная строка корректна }
   Move(p1^, p2^, 128);
   FreeMem(p1, 128);
   FreeMem(p2, 128);
 end;

Перечисленные подходы позволят избежать наиболее частых недочетов в разработке, которые могут вызвать столь неприятное как для пользователя, так и для разработчика сообщение о том, что программа выполнила «недопустимую операцию».

Удачной вам ловли багов, господа!

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Pro tools run out of cpu power ошибка
  • Pro dialog plus carrier коды ошибок