总结一下地址错的几类原因.
来源:互联网 发布:windows nt 4.0 编辑:程序博客网 时间:2024/06/05 17:30
上周在初始化一个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;
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;
- 总结一下地址错的几类原因.
- 总结一下使用过的几类LCD屏特点
- 总结一下常见的几种排序
- 总结一下今天的几点收获
- 总结一下项目拖了很久的原因
- 总结一下最近面试一系列悲剧的原因
- 总结一下由对象名得到对象地址的方法
- 总结一下由对象名得到对象地址的方法
- 总结一下切换git地址 重合代码的过程
- 总结一下Windows常用的几种线程同步技术。
- 总结一下跨域的几种情况
- 总结一下query中ajax的几种方法
- MySQL 无法启动的几种原因总结
- PHP中打开URL地址的几种方法总结
- 总结一下将近4个月没有整理博文的原因
- 看周公的一篇文章,其中总结的几句话很有意义,记录一下
- 小小的总结一下
- 小小的总结一下
- 有人问起C#的LINQ写法
- AspNetPager分页控件的使用
- Sharepoint 开发工具:Visual Studio Extensions for SharePoint Released
- 位运算应用口诀和实例
- ASP.NET中常用的26个优化性能方法
- 总结一下地址错的几类原因.
- 一衣带水
- .Net学习笔记 - IIS内幕
- 省、市、地区三级级联菜单(读数据库那种,Ajax异步调用,局部刷新)
- DLL文件
- (转)ABAP--如何获取SAP标准表的相关的锁(lock)
- 思科 7600 系列路由器
- 新建数据库
- 避开误区全面对比MLC和SLC架构