上周在初始化一个PChar的时候,将fillchar使用错误.直接写成
var
P:PChar;
begin
P:=StrAlloc(1024);
FillChar(P,1024,0);
....
end;
导致在程序运行时莫明其妙的地方报内存错.仔细检查后才发现,原来问题出在 FillChar(P,1024,0);这句上.
正确的写法是 FillChar(P^,1024,0);错误的代码因为P是一个4字节的指针,执行这句后程序将会溢出,错误的将其后的1020字节的内存填0,而这个内存是不可预知的位置.于是便引起内存错误.而这种错误都不会在执行这句代码时报错,这将会给以后的调试带来和大的问题.
另外在项目的登录过程中找到了另外一处类似的溢出错误,原因是穿入dll的PChar分配的内存过小导致程序溢出.
总结之前碰到的内存错的问题:
1.操作已释放或未创建(分配内存)的对象或指针.
调试:这类错误一般在单步的时候能明确的在某一句代码执行时报错,错误地方比较固定,容易复现.
2.由于Delphi的ShareMem单元没放在合适的位置等.
调试:这类内存错一般在使用delphi编写的bpl,dll,ocx等时出现地址错,单步调试时在函数end前未出现错误,而在返回时出现内存错.引起的原因会有可能时在bpl,dll,ocx内使用string为导出函数的参数(强烈建议使用PChar代替,如使用string调用者也是delphi程序要注意调用的project文件里第一个引用ShareMem单元).另外在dll等里面引用Q开头的单元(linux系统使用的程序)也可能会引起这种内存错.
3.不可意料的随机位置的内存错.有时候又没有报错.
调试:出现CPU对话框,错误代码有可能是在带Resource,String的函数的位置,如果出现这种错误,有可能是你的某个地方溢出了.
4.Invalid Point Operation错误
调试:这类错误可能不会报内存地址错,但出现这个错误,你要担心是否程序存在泄露.一般编译器会把程序中的私有变量,常量等内存在栈内分配,而使用GetMem,StrAlloc等函数分配的内存都是在堆里的.如果将堆内存的指针指向了一个栈内存,程序就会报这个错误.
典型的错误是类似以下代码
var
P:PChar;
begin
try
P:=StrAlloc(1024);
P:=PChar('this is a invalid point operation');
finally
StrDispose(P);
end;
以上代码在出现错误的同时也会泄漏1k的内存.
end;