C++ PDF-Writer Access violation reading location错误解决方法
故障原因
触发访问违例、页面属性赋值后全部显示为0的核心原因是API调用顺序和对象创建方式错误:
- PDF-Writer 库的
PDFPage对象强依赖StartPDF执行完成后初始化的文档上下文,直接通过new PDFPage()创建的实例内部成员未完成正确初始化,属于无效对象。 - 对无效对象调用
SetMediaBox、SetRotate等方法时,写入操作会落到未正确分配的内存地址,赋值不会实际生效;后续WritePageAndRelease尝试读取页面属性时,就会触发内存访问违例错误。 - 原代码的执行逻辑
StartPDF→操作提前手动创建的空page对象→写页,完全不符合库的API设计要求。
修复方案
按照库的API设计调整对象创建和调用顺序即可,正确流程如下:
- 初始化
PDFWriter实例,调用StartPDF完成PDF文档上下文创建 - 不要手动
new PDFPage(),通过PDFWriter实例的CreatePage方法获取绑定了当前文档上下文的有效页面对象 - 对有效页面对象执行各类属性设置操作
- 写入页面并释放资源,最后结束PDF文档
修复后的参考代码:
void app::saveaspdf() { // 直接栈上创建实例即可,不需要手动new PDFWriter pdfWriter; pdfWriter.StartPDF("c:\\a.pdf", ePDFVersion13); // ... 其他PDF内容写入逻辑 ... // 基于已初始化的文档上下文创建页面 PDFPage* sheet = pdfWriter.CreatePage(); // 设置页面属性 sheet->SetMediaBox(PDFRectangle(0, 0, 595, 842)); sheet->SetRotate(0); sheet->SetTrimBox(PDFRectangle(0, 0, 595, 842)); sheet->SetCropBox(PDFRectangle(0, 0, 595, 842)); sheet->SetBleedBox(PDFRectangle(0, 0, 595, 842)); sheet->SetArtBox(PDFRectangle(0, 0, 595, 842)); pdfWriter.WritePageAndRelease(sheet); pdfWriter.EndPDF(); }
注意事项
WritePageAndRelease方法会自动释放页面对象内存,不需要手动调用delete释放sheet指针- 所有页面操作必须在
StartPDF执行完成后、EndPDF调用前执行,不要缓存脱离文档上下文的页面对象跨生命周期使用 - 非必要不要手动new
PDFWriter、PDFPage实例,栈上创建PDFWriter、通过CreatePage获取页面对象的方式可以避免绝大多数内存泄漏和野指针问题。
内容的提问来源于stack exchange,提问作者dragonitebrian1024
相关产品推荐
相关产品推荐

