我有一个非常简单的问题,我似乎对所发生的事情感到难过。请查看以下代码:
CArray<double, double&> arr;
arr.SetSize(50000);
for(int i =0; i< 50000; i++)
{
arr[i] = (i+2)*3.14f;
}
arr.RemoveAll();
我认为在RemoveAll()
之后,内存将被释放,但似乎没有发生。要检查内存占用,请打开Taskmanager并观察exe的内存。它会在arr.SetSize()
调用时增加,但即使此arr
超出范围,它也不会减少。有人可以透露一下吗?
答案 0 :(得分:7)
第一件事:
操作系统(或更具体地说是C运行时系统)肯定会缓存你分配的一些内存。
请注意,操作系统通常并不笨 - 如果应用程序没有使用内存,并且操作系统需要更多内存来满足其他程序的内存需求,则会相应地进行分配。但如果情况并非如此(大部分时间都不是这样),那么保留它以供应用程序重用,这是一个成功的策略。
由于这些优化,您实际上无法使用任务管理器来准确查看应用程序的内存使用情况。
第二件事:
与所有非愚蠢的动态数组类一样,即使您需要再次使用内存缓冲区时删除所有元素,CArray
也不释放支持数组的内存。删除底层内存缓冲区只是为了发现你需要浪费更多的处理器周期来重新分配另一个缓冲区以处理可能在{{1}之后发生的下一个CArray::Append()
调用,这将是一个非常浪费的处理器周期}}
如果您真的想要摆脱多余的空间,请使用CArray::FreeExtra()。请注意,该函数可能涉及分配新缓冲区并将元素复制到新缓冲区,然后删除旧缓冲区。
答案 1 :(得分:2)
正如其他人所说,RemoveAll不释放CArray分配的内存,你需要调用CArray :: FreeExtra。
你说在CArray的析构函数之后内存不会消失。 CArray :: SetSize从堆中分配内存,CArray的析构函数释放它。但这并不意味着堆内存被返回给操作系统。
当您使用MFC时,我建议您不时在调试器中启动程序。 MFC调试应用程序在MFC清理期间打印出内存泄漏(基于新内存)。
答案 2 :(得分:1)
您需要在RemoveAll之后调用FreeExtra以获取内存。我猜这是为了避免堆碎片。