Delphi7从自定义记录加载JPEG报错 直接从数据库加载则正常
核心问题
你的getImageFromBlob函数返回的TJPEGImage对象,在函数退出前就被主动释放了,你存在数组里的是已销毁对象的野指针,后续访问必然触发访问违规。
你在注释中提到直接执行image1.picture.graphic := tmpJPEG可以正常运行,是因为TPicture的Graphic属性赋值时会完整拷贝传入的图形对象内容,而非直接持有你传入的对象指针,所以你后续释放tmpJPEG不会影响已经拷贝到Image1里的副本。但你直接把tmpJPEG指针赋值给数组元素时,只是拷贝了指针地址,没有拷贝对象本身,finally块执行tmpJPEG.Free后这个指针指向的内存就已经被回收,后续再访问当然报错。
修复方案
你只需要去掉finally块里的tmpJPEG.Free语句,把对象的生命周期交给调用方管理即可,修改后的函数如下:
function TFormMain.getImageFromBlob: TJPEGImage; var tmpStream: TMemoryStream; tmpJPEG: TJPEGImage; begin Result := nil; tmpStream := TMemoryStream.Create; tmpJPEG := TJPEGImage.Create; try TBlobField(QueryTemp.FieldByName('Afbeelding')).SaveToStream(tmpStream); tmpStream.Position := 0; if tmpStream.Size > 0 then begin tmpJPEG.LoadFromStream(tmpStream); Result := tmpJPEG; end else begin // 加载失败的情况主动释放创建的tmpJPEG,避免内存泄漏 tmpJPEG.Free; end; finally tmpStream.Free; // 注意这里不再释放tmpJPEG,加载成功的对象交给调用方管理 end; end;
额外注意事项
- 后续你不再使用
CarouselPhotoArray数组里的图片时,要主动遍历数组释放所有cpPhotograph字段持有的TJPEGImage对象,避免内存泄漏。 - 给动态数组
CarouselPhotoArray赋值前要先调用SetLength设置正确的数组长度,避免越界访问。
内容的提问来源于stack exchange,提问作者Stefan van Roosmalen
相关产品推荐
相关产品推荐

