RSS订阅 | 匿名投稿
您的位置:网站首页 > 系统 > 正文

DELPHI编写服务程序总结

作者:admin 来源: 日期:2012/5/21 12:14:54 人气: 标签:

一、提高DELPHI程序的稳定性
软件质量是一个产品的生命线,也是关乎软件开发者的幸福关键所在,每天有很多程序员都在因为软件质量而通宵达旦的加班,经常遇到的情况是刚发布的程序不停的发布补丁包。软件质量就像一个噩梦一样,不停的在后面追赶着程序员,让他们疲于奔命,甚至于在程序员中流传着一句话:“生命不息,BUG不止”。
今天我们要探究的不是哪些可以重现的BUG,我们把哪些可以重现的BUG不定义为BUG,只有哪些不可重现的BUG,会让你茶饭不思、坐立不安。我曾在一家公司开发服务器软件,结果因为程序不稳定,而且都是一些不可重现的错误,导致我们需要不停的派人盯着服务器运行。不稳定就像一个恶鬼一样终日萦绕在我们心头,领导的不停催促,客户的不停投诉,让我们项目组个个疲于奔命,叫苦连天。我在查了无数个不可重现的BUG发现,主要是由于以下八种原因引起的: 
1. 变量没有初始化;
2. 函数返回值没有初始化;
3. 编译优化导致的错误;
4. 函数递归;
5. 消息重入;
6. 野指针;
7. 内存泄漏;
8. 并发;
你会发现都是一些细小问题,因此程序员在日常开发中一定要养成好的习惯。
二、变量没有初始化
DELPHI默认初始化的变量是:全局变量、类成员,其它在函数体的变量都不会初始化,因此一些用于判断或者循环的变量一定要记得初始化,另外枚举类型、申请的内存都需要初始化,PCHAR一定要在末尾加#0。例如:下面的返回结果有可能会出现乱码。
function TempPath: string;
begin
SetLength(Result, GetTempPath(0, PChar(Result)));
GetTempPath(Length(Result), PChar(Result));
Result := PChar(Result);
end;
正确的写法应该
function TempPath: string;
begin
SetLength(Result, GetTempPath(0, PChar(Result)));
ZeroMemory(PChar(Result), Length(Result));
GetTempPath(Length(Result), PChar(Result));
Result := PChar(Result);
end;
这个程序就是典型的在申请内存的时候,没有对PCHAR进行初始化,因此末尾有可能是随机值,但是通过ZeroMemory就把末尾赋#0。
三、函数返回值没有初始化
在DELPHI中退出函数是使用Exit函数的,有很多函数在退出的时候,没有对函数返回值初始化,那么函数的返回值返回就是一个随机值,对程序运行造成不可重现错误。例如:下面程序的执行结果会让你大吃一惊。
procedure NotInitResult;
var 
i: Integer;
function GetString(AValue: Integer): string;
begin
    if AValue = 0 then
      Result := 'True';
end;
begin
for i := -1 to 1 do
begin
    ShowMessage(GetString(i));
end;
end; 
你看到的运行结果是:‘’、‘True’、‘True’,正确的写法应该是:
procedure NotInitResult;
var 
i: Integer;
function GetString(AValue: Integer): string;
begin
    if AValue = 0 then
      Result := 'True'
     else
       Result := ‘’;
end;
begin
for i := -1 to 1 do
begin
    ShowMessage(GetString(i));
end;
end; 
因此针对if或者Case语句一定要赋初始值,上面的函数的写法也可以写为:
function GetString(AValue: Integer): string;
begin
Result := ‘’;
if AValue = 0 then
    Result := 'True';
end;
function GetString(AValue: Integer): string;
begin
case AValue of
    0: Result := ‘True’;
    else Result := ‘’;
end;
end;
四、编译优化导致的错误
现在的编译器在编译代码的时候会优化掉一些可以不执行的代码,例如:布尔类型优化是最常见的一种,下面的例子能很好的说明这个问题。
procedure TForm1.btn1Click(Sender: TObject);
var 
s: string;
begin
if GetTrue or GetValue1(s) then
    ShowMessage('Hello ' + s);
end; 
procedure TForm1.btn2Click(Sender: TObject);
var 
s: string;
begin
if GetTrue or GetValue2(s) then
    ShowMessage('Hello ' + s);
end; 
function TForm1.GetTrue: Boolean;
begin
Result := True;
end;
function TForm1.GetValue1(var s: string): Variant;
begin
Result := True;
s := 'World';     
end;
function TForm1.GetValue2(var s: string): Boolean;
begin
Result := True;
s := 'World';
end; 
你会发现单击btn1时出现的结果是:“Hello Word”,但是单击btn2的时候是:“Hello”,这个就是因为单击btn2的时候由于GetTrue返回的是真,所以第二句不执行,但是btn1由于还要进行Variant到Boolean类型的转换,因此肯定会执行。

读完这篇文章后,您心情如何?
0
0
0
0
0
0
0
0
本文网址: