- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有以下继承自 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 时,这很正常,没有内存不足异常,任务管理器中的内存也很稳定,就像这个镜头一样
我尝试了以下2种状态
当我重新编译解决方案时我的解释有一些错误 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我感谢所有试图帮助解决这个问题的人,我希望它能有所帮助。
最佳答案
从一个没有虚拟析构函数的类继承是一个非常糟糕的主意。以下引自 Scott Meyers 的“Effective C++:改进程序和设计的 55 种具体方法,第三版”。
The problem is that getTimeKeeper returns a pointer to a derived class object (e.g., AtomicClock), that object is being deleted via a base class pointer (i.e., a TimeKeeper* pointer), and the base class (TimeKeeper) has a non-virtual destructor. This is a recipe for disaster, because C++ specifies that when a derived class object is deleted through a pointer to a base class with a non-virtual destructor, results are undefined. What typically happens at runtime is that the derived part of the object is never destroyed. If a call to getTimeKeeper happened to return a pointer to an AtomicClock object, the AtomicClock part of the object (i.e., the data members declared in the AtomicClock class) would probably not be destroyed, nor would the AtomicClock destructor run. However, the base class part (i.e., the TimeKeeper part) typically would be destroyed, thus leading to a curious “partially destroyed” object. This is an excellent way to leak resources, corrupt data structures, and spend a lot of time with a debugger.
总而言之,当您从没有虚析构函数的类派生时,您会使用指向该对象的指针,当您删除该指针时,该对象只会部分销毁。这显然只发生在指针指向基类而不是指针指向类本身时。
如果您必须扩展一个没有虚拟析构函数的类,最好通过包含来实现。那就是创建一个新类,它不是从您希望扩展的类派生的。然后拥有一个您希望扩展的类型的成员变量,并实现您希望扩展的类中的所有函数,作为您希望扩展的类中适当函数的包装器。
例如。
class TString /* do not derive from CString */
{
private:
CString m_string;
TString() :
m_string()
{
}
TString(const TCHAR *str) :
m_string(str)
{
}
int GetLength() const
{
return m_string.GetLength();
}
/* All the other functions in the CString class here. */
/* Your additions to the CString class here. */
}
当然,在最新版本的 MFC 中,CString 实际上是一个模板类,因此您也许应该将您的类设为模板类,如下所示。
template< typename BaseType >
class TStringT
{
/* The same as above but use BaseType instead of TCHAR. */
}
然后执行以下操作。
typedef TStringT< wchar_t > TStringW;
typedef TStringT< char > TStringA;
typedef TStringT< TCHAR > TString;
希望对您有所帮助。
关于c++ - 继承自 CString 导致内存不足异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21738026/
我在具有 2CPU 和 3.75GB 内存 (https://aws.amazon.com/ec2/instance-types/) 的 c3.large Amazon EC2 ubuntu 机器上运
我想通过用户空间中的mmap-ing并将地址发送到内核空间从用户空间写入VGA内存(视频内存,而不是缓冲区),我将使用pfn remap将这些mmap-ed地址映射到vga内存(我将通过 lspci
在 Mathematica 中,如果你想让一个函数记住它的值,它在语法上是很轻松的。例如,这是标准示例 - 斐波那契: fib[1] = 1 fib[2] = 1 fib[n_]:= fib[n] =
我读到动态内存是在运行时在堆上分配的,而静态内存是在编译时在堆栈上分配的,因为编译器知道在编译时必须分配多少内存。 考虑以下代码: int n; cin>>n; int a[n]; 如果仅在运行期间读
我是 Python 的新手,但我之前还不知道这一点。我在 for 循环中有一个基本程序,它从站点请求数据并将其保存到文本文件但是当我检查我的任务管理器时,我发现内存使用量只增加了?长时间运行时,这对我
我正在设计一组数学函数并在 CPU 和 GPU(使用 CUDA)版本中实现它们。 其中一些函数基于查找表。大多数表占用 4KB,其中一些占用更多。基于查找表的函数接受一个输入,选择查找表的一两个条目,
读入一个文件,内存被动态分配给一个字符串,文件内容将被放置在这里。这是在函数内部完成的,字符串作为 char **str 传递。 使用 gdb 我发现在行 **(str+i) = fgetc(aFil
我需要证实一个理论。我正在学习 JSP/Java。 在查看了一个现有的应用程序(我没有写)之后,我注意到一些我认为导致我们的性能问题的东西。或者至少是其中的一部分。 它是这样工作的: 1)用户打开搜索
n我想使用memoization缓存某些昂贵操作的结果,这样就不会一遍又一遍地计算它们。 两个memoise和 R.cache适合我的需要。但是,我发现缓存在调用之间并不可靠。 这是一个演示我看到的问
我目前正在分析一些 javascript shell 代码。这是该脚本中的一行: function having() { memory = memory; setTimeout("F0
我有一种情况,我想一次查询数据库,然后再将整个数据缓存在内存中。 我得到了内存中 Elasticsearch 的建议,我用谷歌搜索了它是什么,以及如何在自己的 spring boot 应用程序中实现它
我正在研究 Project Euler (http://projecteuler.net/problem=14) 的第 14 题。我正在尝试使用内存功能,以便将给定数字的序列长度保存为部分结果。我正在
所以,我一直在做 Java 内存/注意力游戏作业。我还没有达到我想要的程度,它只完成了一半,但我确实让 GUI 大部分工作了......直到我尝试向我的框架添加单选按钮。我认为问题可能是因为我将 JF
我一直在尝试使用 Flask-Cache 的 memoize 功能来仅返回 statusTS() 的缓存结果,除非在另一个请求中满足特定条件,然后删除缓存。 但它并没有被删除,并且 Jinja 模板仍
我对如何使用 & 运算符来减少内存感到非常困惑。 我可以回答下面的问题吗? clase C{ function B(&$a){ $this->a = &$a; $thi
在编写代码时,我遇到了一个有趣的问题。 我有一个 PersonPOJO,其 name 作为其 String 成员之一及其 getter 和 setter class PersonPOJO { priv
在此代码中 public class Base { int length, breadth, height; Base(int l, int b, int h) { l
Definition Structure padding is the process of aligning data members of the structure in accordance
在 JavaScript Ninja 的 secret 中,作者提出了以下方案,用于在没有闭包的情况下内存函数结果。他们通过利用函数是对象这一事实并在函数上定义一个属性来存储过去调用函数的结果来实现这
我正在尝试找出 map 消耗的 RAM 量。所以,我做了以下事情;- Map cr = crPair.collectAsMap(); // 200+ entries System.out.printl
我是一名优秀的程序员,十分优秀!