我使用BDS 2006 Turbo C++已经很长时间了,我的一些大型项目(CAD/CAM、3D gfx 引擎和天文计算)偶尔会抛出异常(例如,在 3-12 个月的 24/7 重型使用中) )。经过大量调试后,我发现:
//code1:
struct _s { int i; } // any struct
_s *s=new _s[1024]; // dynamic allocation
delete[] s; // free up memory
此代码通常在模板中,其中_s
也可以是类,因此delete[]
此代码应该可以正常工作,但delete[]
对于结构不能正常工作(类看起来不错)。没有抛出异常,内存被释放,但它以某种方式损坏了内存管理器分配表,在此之后任何新的分配都可能是错误的(新的可以创建与已分配空间甚至未分配空间的重叠分配,因此偶尔会出现异常)
我发现如果我添加空析构函数_s
比突然看起来一切正常
struct _s { int i; ~_s(){}; }
那么现在是奇怪的部分。在我将其更新到我的项目后,我发现AnsiString
该类的重新分配也很糟糕。例如:
//code2:
int i;
_s *dat=new _s[1024];
AnsiString txt="";
// setting of dat
for (i=0;i<1024;i++) txt+="bla bla bla\r\n";
// usage of dat
delete[] dat;
在此代码dat
中包含一些有用的数据,然后是txt
通过添加行创建的一些字符串,因此txt
必须重新分配几次,有时dat
数据会被覆盖txt
(即使它们没有重叠,我AnsiString
认为重新分配所需的 temptxt
与重叠dat
)
所以我的问题是:
- 我在 code1, code2 中做错了吗?
有什么办法可以避免
AnsiString
(重新)分配错误?(但仍在使用它)- 经过大量调试(在发布问题 2 之后)我发现
AnsiString
不会导致问题。它们仅在使用它们时出现。真正的问题可能在于OpenGL客户端之间的切换。我有带有矢量图形预览的打开/保存对话框。如果我禁用这些VCL子窗口的OpenGL使用,那么内存管理错误就会完全消失。我不支持是什么问题(MFC/VCL之间不兼容AnsiString
窗口之间的不兼容,或者更可能是我在切换上下文时犯了一些错误,将进一步调查)。关注的OpenGL窗口是: - 主VCL窗体 + OpenGL
Canvas
客户区内的 - 主MFC打开/保存对话框的子级 + 停靠预览VCL表单 +客户端区域内的OpenGL
Canvas
- 经过大量调试(在发布问题 2 之后)我发现
附言
- 这些错误取决于数量
new/delete/delete[]
不是分配的大小 - code1 和 code2 错误都是重复的(例如,有一个解析器来加载复杂的 ini 文件,如果 ini 没有更改,则错误发生在同一行)
- 我仅在大型项目(纯源代码> 1MB)上检测到这些错误,并结合使用
AnsiString
和模板与内部动态分配,但它们也可能出现在更简单的项目中,但很少发生以至于我错过了它。 - 受感染的项目规格:
- win32 noinstall 独立(使用Win7sp1 x64但在XPsp3 x32上的行为相同)
- 如果使用GDI或OpenGL/GLSL
- 不计量是否使用设备驱动程序DLL
- 没有OCX或非标准VCL组件
- 没有DirectX
- 1 字节对齐的编译/链接
- 不要使用RTL、包或框架(独立)
抱歉英语/语法不好......任何帮助/结论/建议表示赞赏。