我在Windows上用C ++写了一个小队列类。
为了测试,我正在分配1,0000,000 int
并将其读回来。
队列正在正常工作并且速度非常快,但问题是在完全取消分配后,任务管理器会报告一些内存使用情况。例如,我仍然可以获得2MB的内存,尽管所有这些整数都会导致400MB +的内存。
我认为这是由于操作系统没有执行某种GC或其他任何操作系统,但现在我发现当我分配100,000,000个整数(前一个数字的10倍)时,这个值(2MB)变为13MB。我找不到泄漏。
这是代码;如你所见,我解除了所有的一切:
#pragma once
#include <exception>
template <class T>
class colist_item
{
public:
colist_item() { }
~colist_item() { }
T value;
colist_item *next;
};
template <class T>
class colist
{
public:
colist() { this->m_root = NULL; this->m_count = 0; }
~colist() { }
void enqueue(T value);
T dequeue();
T *peek();
int count();
private:
colist_item<T> *m_root;
int m_count;
};
template <class T>
void colist<T>::enqueue(T value)
{
if (this->m_root == NULL) {
this->m_root = new colist_item<T>();
this->m_root->value = value;
this->m_root->next = NULL;
} else {
colist_item<T> *tempitem = new colist_item<T>();
tempitem->value = value;
tempitem->next = this->m_root;
this->m_root = tempitem;
}
this->m_count++;
}
template <class T>
T colist<T>::dequeue()
{
if (this->m_root == NULL) {
throw std::exception();
} else {
T retval = this->m_root->value;
colist_item<T> *next = this->m_root->next;
delete this->m_root;
this->m_root = next;
this->m_count--;
return retval;
}
}
template <class T>
T *colist<T>::peek()
{
if (this->m_root == NULL) {
return NULL;
} else {
T retval = this->m_root->value;
return &retval;
}
}
template <class T>
int colist<T>::count()
{
return this->m_count;
}
主:
#include <iostream>
#include <limits>
#include "colist.h"
#include <time.h>
const int kNumItems = 100000000;
using namespace std;
void puttest(colist<int> *list)
{
for(int i = 0; i < kNumItems; i++)
list->enqueue(i);
}
void readtest(colist<int> *list)
{
for(int i = 0; i < kNumItems; i++)
list->dequeue();
}
int main(int argc, char *argv[])
{
colist<int> list;
cout << "Testing with : " << kNumItems << " elements" << endl;
clock_t start = clock();
puttest(&list);
clock_t end = clock();
double ms = ((end - start));
cout << "puttest: " << ms << endl;
start = clock();
readtest(&list);
end = clock();
ms = ((end - start));
cout << "readtest: " << ms << endl;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
答案 0 :(得分:2)
确定有几个错误。
您没有泄漏任何内存,因为您删除了所有项目。但是如果你没有手动删除它们,那么当它超出范围时你的类会泄漏。添加一个只删除列表中所有项的析构函数。
T retval = this->m_root->value;
colist_item<T> *next = this->m_root->next;
delete this->m_root; // If T is badly designed it could potentially throw an exception.
this->m_root = next; // Now you have m_root pointing at a bad object. The idea is to
// make sure an exception can not damage your internal structure
// of your object. Thus remove it from the chain before you call
// delete.
// Like this
T retval = m_root.value;
colist_item<T>* oldhead = m_root;
m_root = oldhead->next;
// Internal structure updated.
// Safe to do dangerous tasks.
delete oldhead;
colist() { this->m_root = NULL; this->m_count = 0; }
// should be
colist(): m_root(NULL), m_count(0) {}
this
。我知道在java中鼓励它,但在C ++中它通常是气馁的,但被认为是一种风格的东西。就个人而言,我觉得它的用途很混乱。
答案 1 :(得分:2)
运行http://valgrind.org/以确保没有内存泄漏。
如何告诉操作系统我已经完成了分配,它可以释放未分配的内存?
当您要求更多内存时,c ++库将重用OS提供的内容。 所以,一般来说,这不是问题。
有时,由于内存碎片,一些内存块确实难以回收。 在这种情况下,您可能想要使用Arena Allocator。
答案 2 :(得分:0)
正如评论中所提到的,您不应该依赖任务管理器来分析程序的内存使用情况。 This question列出了几种适用于内存泄漏检测的Windows工具。