首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++新内存分配碎片

C++新内存分配碎片
EN

Stack Overflow用户
提问于 2010-04-28 04:14:11
回答 5查看 1.3K关注 0票数 4

我试图了解新分配器的行为,以及为什么它不能连续放置数据。

我的代码:

代码语言:javascript
复制
struct ci {
    char c;
    int i;
}

template <typename T>
void memTest()
{
    T * pLast = new T();
    for(int i = 0; i < 20; ++i) {
         T * pNew = new T();
         cout << (pNew - pLast) << " ";
         pLast = pNew;
    }
}

所以我用char,int,ci来运行。大多数分配都是从上一块开始的固定长度,有时会出现从一个可用块到另一个块的奇怪跳跃。

sizeof(char):1

平均跳跃: 64字节

sizeof(int):4

平均跳跃: 16

sizeof(ci):8 (int必须放在4字节对齐上)

平均跳跃:9

谁能解释一下为什么分配器会像这样把内存分成碎片?还有,为什么char的跳转比int和包含int和char的结构要大得多。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-04-28 04:22:27

有两个问题:

  • 大多数分配器在块开始之前存储一些额外的数据(通常块大小和几个pointers)
  • there通常是对齐要求-现代操作系统通常至少分配到8字节的边界。

因此,您几乎总是会在连续分配之间获得某种类型的差距。

当然,对于这样的事情,你永远不应该依赖于任何特定的行为,在这种情况下,实现可以随心所欲。

票数 10
EN

Stack Overflow用户

发布于 2010-04-28 04:23:24

你的代码包含一个bug,为了知道指针的距离,将它们转换为(char *),否则增量是sizeof(T)。

票数 6
EN

Stack Overflow用户

发布于 2010-04-28 04:47:35

这不是碎片,它只是将分配的大小四舍五入为四舍五入的块大小。

在一般的编程中,你不应该注意像new这样的通用分配器返回的内存地址的模式。当你关心分配行为时,你应该总是使用一个特殊用途的分配器(boost::pool,你自己写的东西,等等)

例外的是,如果你正在研究分配器,在这种情况下,你可以做得更差,而不是为一个简单的分配器拿起你的K&R副本,这可能有助于你理解new是如何获得它的内存的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2724722

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档