记忆去了哪里?
where did the memory go?
class Node
{
//some member variables.
};
std::cout<<"size of the class is "<<sizeof(Node)<<"\n";
int pm1 =peakmemory();
std::cout<<"Peak memory before loop is "<< pm1<<"\n";
for(i=0; i< nNode; ++i)
{
Node * p = new Node;
}
int pm2 =peakmemory();
std::cout<<"Peak memory after loop is "<< pm2<<"\n";
我认为 pm2-pm1
接近 nNode * sizeof(Node)
。但事实证明 pm2-pm1
比 nNode *sizeof(Node)
大得多。记忆去了哪里?我怀疑 sizeof(Node)
没有反映正确的内存使用情况。
我已经在 Windows 和 linux 上进行了测试。最终结论是 Node * p = new Node;
将分配大于 sizeof(Node)
的内存,其中 Node
是 class.
由于您没有指定您 运行 在哪个平台上,这里有几种可能性:
- 分配大小:您的 C++ 实现可能以大于
sizeof(Node)
的单位分配内存,例如限制它的簿记量。
- 对齐:分配器可能有一个返回地址与 2 的最小幂对齐的策略。同样,这可能会稍微简化其实现。
- 开销:一些分配器,除了你正在使用的内存之外,还有一些具有固定模式的填充以防止内存损坏;或分配器使用的一些元数据。
这并不是说这 实际上 发生了。但它可以;它当然符合语言规范 (AFAICT)。
几乎所有内存分配器(例如 linux/win32 上的内存分配器)都有一个分配 header 来进行内存分配(包括有关分配大小的信息)。例如,在 linux 上,您可以查看 malloc 的源代码,它提供了有关存储的 header 的信息(以及如何计算其大小):
https://git.busybox.net/uClibc/tree/libc/stdlib/malloc/malloc.h#n106
正如评论中已经提到的,调试版本还可以在分配的任一侧分配额外的字节,以防止缓冲区溢出错误。
class Node
{
//some member variables.
};
std::cout<<"size of the class is "<<sizeof(Node)<<"\n";
int pm1 =peakmemory();
std::cout<<"Peak memory before loop is "<< pm1<<"\n";
for(i=0; i< nNode; ++i)
{
Node * p = new Node;
}
int pm2 =peakmemory();
std::cout<<"Peak memory after loop is "<< pm2<<"\n";
我认为 pm2-pm1
接近 nNode * sizeof(Node)
。但事实证明 pm2-pm1
比 nNode *sizeof(Node)
大得多。记忆去了哪里?我怀疑 sizeof(Node)
没有反映正确的内存使用情况。
我已经在 Windows 和 linux 上进行了测试。最终结论是 Node * p = new Node;
将分配大于 sizeof(Node)
的内存,其中 Node
是 class.
由于您没有指定您 运行 在哪个平台上,这里有几种可能性:
- 分配大小:您的 C++ 实现可能以大于
sizeof(Node)
的单位分配内存,例如限制它的簿记量。 - 对齐:分配器可能有一个返回地址与 2 的最小幂对齐的策略。同样,这可能会稍微简化其实现。
- 开销:一些分配器,除了你正在使用的内存之外,还有一些具有固定模式的填充以防止内存损坏;或分配器使用的一些元数据。
这并不是说这 实际上 发生了。但它可以;它当然符合语言规范 (AFAICT)。
几乎所有内存分配器(例如 linux/win32 上的内存分配器)都有一个分配 header 来进行内存分配(包括有关分配大小的信息)。例如,在 linux 上,您可以查看 malloc 的源代码,它提供了有关存储的 header 的信息(以及如何计算其大小):
https://git.busybox.net/uClibc/tree/libc/stdlib/malloc/malloc.h#n106
正如评论中已经提到的,调试版本还可以在分配的任一侧分配额外的字节,以防止缓冲区溢出错误。