【发布时间】:2014-03-11 08:59:00
【问题描述】:
我有以下从 MFC CString 继承的字符串类
class TString : public CString
{
public:
TString() : CString(_T(""))
{
}
TString(LPCTSTR str) : CString(str)
{
}
};
我在一个经常使用带有 TString 的 + 运算符的方法中出现内存不足异常,所以我尝试进行如下测试
TString str;
TCHAR buffer[] = "Hello world, Hello world, Hello world, Hello world, Hello world, Hello world";
uint i = 0;
while(i++ < 100000000)
{
str = buffer;
str += buffer;
}
占用大量内存并以内存不足异常结束这是在执行最后一个代码后从任务管理器更改内存的镜头
当我用 CString 替换 TString 时,这是正常的花费时间并且没有内存不足异常,并且内存在任务管理器中是稳定的,就像这张照片一样
我尝试了以下两种状态
- 我创建了另一个 exe 应用程序,它依赖于包含 TString 类的同一个库,它像 CString 一样工作得非常好
- 我在 while 循环中调用了 Sleep(1),它导致内存快速变化,并且也很稳定 我该怎么做才能解决这样的问题??
编辑:
当我重新编译解决方案时,我的解释中有一些错误 CString 也有相同的行为,即使是 std::string 我认为新的运算符重载我创建了一个自定义类,它调用 malloc 并在析构函数中释放它也导致对于相同的行为,我将该测试代码移动到我的应用程序的第一个入口点到我的应用程序的构造函数,该构造函数继承自 CWinAppEx 代码工作正常然后我查看了 InitInstance 我发现内存泄漏检测 4 行代码如下
int tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
tmpDbgFlag |= _CRTDBG_DELAY_FREE_MEM_DF;//<====this is the evil after comment everything is fine
tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF;
_CrtSetDbgFlag(tmpDbgFlag);
我一直都知道这是人为的错误。这会导致灾难。
我刚刚评论了这一行
tmpDbgFlag |= _CRTDBG_DELAY_FREE_MEM_DF;
解决了。 这个答案还谈到了这个标志的用法Finding heap corruption 我感谢大家试图帮助解决这个问题,我希望它会有所帮助。
【问题讨论】:
-
1) 为什么要从 CString 继承? 2) 验证 CString-only 代码没有导致编译器优化掉那个循环。
-
@PaulMcKenzie:真的,我正在移植写在 OWL 库顶部的旧代码以使用 MFC,使用的字符串类型是 TString 并且有一些自定义方法,它在代码中被大量使用,所以我让它继承自 CString 并提供这些方法,现在软件正在测试中,这是一个错误。
-
当你继承一个类你需要重新定义所有的构造函数和操作符,我认为
-
顺便说一句,创建一个 typedef 怎么样?
-
@cha:我说最大的问题是其他代码中大量使用了 Tstring 的自定义方法,而 CString 中没有。并且操作符已经被继承了,但是我定义了调用父 CString 构造函数的构造函数。
标签: c++ mfc out-of-memory cstring