C++ 为什么我的自定义堆栈类使用了这么多内存?
我在单链表的基础上制作了自己的堆栈,它工作得很好,但是当我 查看了内存使用情况。。。 使用包含100k整数的堆栈的控制台应用程序占用了6.5MB。这很糟糕,因为4字节*100k=0.38MB。我为每个“单元”结构分配内存,其中一个包含指向下一个的指针,但我认为这不会占用很多内存。问题的原因是什么C++ 为什么我的自定义堆栈类使用了这么多内存?,c++,memory-management,stack,C++,Memory Management,Stack,我在单链表的基础上制作了自己的堆栈,它工作得很好,但是当我 查看了内存使用情况。。。 使用包含100k整数的堆栈的控制台应用程序占用了6.5MB。这很糟糕,因为4字节*100k=0.38MB。我为每个“单元”结构分配内存,其中一个包含指向下一个的指针,但我认为这不会占用很多内存。问题的原因是什么 template <typename T> class Stack { struct Unit { Unit *prev; T val
template <typename T>
class Stack
{
struct Unit
{
Unit *prev;
T value;
Unit(T value);
};
public:
Stack();
void Push(T value);
int Count();
T Top();
T Pop();
~Stack();
private:
unsigned int count;
Unit *top;
};
template<typename T>
Stack<T>::Unit::Unit(T value)
{
this->value = value;
prev = nullptr;
}
template<typename T>
Stack<T>::Stack()
{
top = nullptr;
count = 0;
}
template<typename T>
void Stack<T>::Push(T value)
{
if (top == nullptr)
{
top = new Unit(value);
}
else
{
Unit *tmp = new Unit(value);
tmp->prev = top;
top = tmp;
}
count++;
}
template<typename T>
T Stack<T>::Pop()
{
T value = top->value;
Unit *tmp = top->prev;
delete top;
top = tmp;
count--;
return value;
}
template<typename T>
Stack<T>::~Stack()
{
Unit *curr = top;
if (!curr)
{
return;
}
while (curr)
{
Unit* tmp = curr->prev;
delete curr;
curr = tmp;
}
}
模板
类堆栈
{
结构单元
{
单位*prev;
T值;
单位(T值);
};
公众:
堆栈();
空隙推力(T值);
int Count();
T-Top();
T Pop();
~Stack();
私人:
无符号整数计数;
单位*顶部;
};
模板
堆栈::单位::单位(T值)
{
这个->值=值;
prev=nullptr;
}
模板
Stack::Stack()
{
top=nullptr;
计数=0;
}
模板
无效堆栈::推送(T值)
{
if(top==nullptr)
{
top=新单位(值);
}
其他的
{
单位*tmp=新单位(值);
tmp->prev=顶部;
top=tmp;
}
计数++;
}
模板
T Stack::Pop()
{
T值=顶部->值;
单位*tmp=top->prev;
删除顶部;
top=tmp;
计数--;
返回值;
}
模板
堆栈::~Stack()
{
单位*电流=顶部;
如果(!curr)
{
返回;
}
while(curr)
{
单位*tmp=curr->prev;
删除curr;
curr=tmp;
}
}
在计算大小时,没有考虑指针的大小和结构的任何填充。在您的平台上,指针可能是4或8个字节。此处讨论填充:
我在构造器中为堆栈添加了一个cout,以显示结构单元的大小:
#include <iostream>
template<typename T>
Stack<T>::Stack()
{
top = nullptr;
count = 0;
std::cout << "The size of each unit is " << sizeof(Unit) << " bytes." << std::endl;
}
// Rest of code is copied directly from the question.
int main() {
Stack<int> myStack;
return 0;
}
完整示例如下:
编辑:
在看到提出问题的人正在使用VisualStudio之后,我进行了一些额外的调试以了解情况。在调试模式下,调试运行时向每个分配添加额外的空间,以允许堆损坏检测和堆跟踪。我在main结束之前设置了一个断点,并查看了TaskManager中的内存使用情况(是的,这不是最准确的度量)。在调试模式下,整个应用程序使用了超过12MB的内存,而在发布模式下,总内存使用量为2.6MB
每个区块的额外分配信息如下:
堆函数的调试版本调用标准或基函数
发布版本中使用的版本。当您请求内存块时
调试堆管理器从基本堆中分配稍大的
内存块,并返回指向该部分的指针
从那个街区出去。例如,假设您的应用程序包含
电话:malloc(10)。在发布版本中,malloc将调用base
请求分配10字节的堆分配例程。在一个
然而,调试构建时,malloc将调用_malloc_dbg,然后
调用基本堆分配例程,请求分配10
字节加上大约36字节的额外内存。所有的
调试堆中产生的内存块以单个内存块连接
链表,根据分配时间排序
使用包含100k整数的堆栈的控制台应用程序占用了6.5MB。这很糟糕,因为4字节*100k=0.38MB。您没有计算指针的大小。这应该是4或8个字节。您的结构也可能有填充。打印(单元)的sizeof
以查看每个Unit
占用的空间。您如何测量内存?你知道6.5MB中有多少是典型的开销吗?当你完成实验时,只需使用你基本上有一个链表。下面是我在第一条评论中提到的一个例子:
The size of each unit is 16 bytes.