首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态分配将数据存储在堆中的随机位置?

动态分配将数据存储在堆中的随机位置?
EN

Stack Overflow用户
提问于 2019-03-16 16:10:28
回答 3查看 340关注 0票数 3

我知道局部变量将按顺序存储在堆栈中。

但是,当我在c++中动态分配堆内存中的变量时,就像这样。

代码语言:javascript
复制
int * a = new int{1};
int * a2 = new int{2};
int * a3 = new int{3};
int * a4 = new int{4};

问题1:这些变量是否存储在连续的内存位置?问题2:如果不是,是因为动态分配将变量存储在堆内存中的随机位置吗?Question3 :那么动态分配是否会增加缓存未命中的可能性,并具有低空间局部性?

EN

回答 3

Stack Overflow用户

发布于 2019-03-16 16:34:10

第1部分:单独分配是连续的吗?

答案可能不是,而是。动态分配的发生方式取决于实现。如果您像上面的例子那样分配内存,两个单独的分配可能是连续的,但不能保证会发生这种情况(而且不应该依赖它)。

c++的不同实现使用不同的算法来决定如何分配内存。

第2部分:分配是随机的吗?

内存不是以故意随机的方式分配的。内存分配器通常会尝试分配彼此附近的内存块,以最小化页面错误和缓存未命中,但并不总是可以做到这一点。

分配分两个阶段进行:

  1. 分配器从OS
  2. 请求一大块内存,并在您调用
  3. 时返回该大块的内存,直到您请求的内存超过了它必须提供的内存,在这种情况下,它会从OS请求另一个大块。

在第二个阶段,实现可以尝试为您提供接近其他最近分配的内存,但是它对第一阶段几乎没有控制(操作系统通常只提供任何可用的内存,而不知道您的程序所分配的其他内存)。

第3部分:避免缓存未命中

如果缓存未命中是代码中瓶颈,

  • 试图减少间接量(通过让数组按值而不是指针存储对象);
  • 确保您正在操作的内存在设计允许的情况下是尽可能连续的(因此使用std::数组或std::vector,而不是链表,并且更喜欢一些大的分配而不是许多小的分配);
  • 尝试设计算法,以便它必须尽可能少地在内存中跳转。

一个很好的通用原则是只使用对象的std::vector,除非你有很好的理由使用更花哨的东西。因为它们具有更好的缓存局部性,所以在插入和删除元素时,std::vector比std::list更快,甚至可以插入和删除数十个甚至数百个元素。

最后:试着利用堆栈。除非有很好的理由让某些东西成为指针,否则只需声明为堆栈上的变量即可。如果可能的话,

  • 更喜欢使用MyClass x{};而不是MyClass* x = new MyClass{};
  • 更喜欢使用std::vector<MyClass>而不是std::vector<MyClass*>

通过扩展,如果您可以使用静态多态性(即,模板),请使用它而不是动态多态性。

票数 1
EN

Stack Overflow用户

发布于 2019-03-16 16:52:58

IMHO这是操作系统特定的/ C++标准库实现。

new最终使用较低级别的虚拟内存分配服务,并使用mmap和munmap等系统调用一次分配多个页面。new的实现可以在相关情况下重用先前释放的内存空间。new的实现可以对“大”和“小”分配使用各种不同的策略。

在为内存分配(通常是几个页面)的系统调用中提供第一个new结果的示例中,分配的内存可能足够大,因此后续的new调用会产生连续的allocation..But,这取决于实现

票数 0
EN

Stack Overflow用户

发布于 2019-03-16 17:07:18

简而言之:

  1. not at all (由于对齐而存在填充,堆管理数据,分配的块可能会被重用等),
  2. generally at all (AFAIK,堆算法是确定性的,没有任何随机性),
  3. generally yes (例如,内存池在这里可能会有所帮助)。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55194751

复制
相关文章

相似问题

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