realloc 返回了一个很靠近 stack 区的内存地址?是什么黑科技优化么?

2021-07-18 14:21:03 +08:00
 dangyuluo

发现了一个知识盲点。当我用malloc申请很大一段内存(100000 * sizeof(int))的时候,返回一个0x229feb0地址,看大小应该是处于 heap 区,很合理。但是当我用realloc重新修改大小为 100001 后,居然返回了0x7f6317307010,看大小好像是处于 stack 区?

同时我发现,如果malloc只申请一小段内存(比如 100 个int大小),再用realloc修改为 101 个int大小,则不会出现这个问题。返回的地址都似乎是处于 heap (0x2394ef00x2393eb0)。

请问这可能是什么缘故呢?我看了下汇编代码似乎除了数字之外其余都一样。

示例代码:

  1. 申请 100 个int https://godbolt.org/z/93PoWWdcb
  2. 申请 100000 个int https://godbolt.org/z/8oYG3s8Mc
2124 次点击
所在节点    C
7 条回复
GeruzoniAnsasu
2021-07-18 14:27:24 +08:00
…… 什么叫看大小处于 stack 区,一个进程是可以分配很多个 heap 区的,建议确认一下内存映射,我猜只是给你分了一块新的 heap 而已
codehz
2021-07-18 14:35:27 +08:00
(linux 的 glibc 会在一定范围内使用 brk,超过的就是 mmap
dangyuluo
2021-07-18 14:40:06 +08:00
@GeruzoniAnsasu 我知道 heap 在真实内存里很跳跃,但是这是虚拟地址,不太明白为什么会从 heap 另一端取地址


@codehz 很有道理!我还在猜是不是有个阈值使 malloc 有不同的操作
mons
2021-07-18 15:13:22 +08:00
#2 说的应该是 `M_MMAP_THRESHOLD`: https://elixir.bootlin.com/glibc/glibc-2.33/source/malloc/malloc.c#L707

https://stackoverflow.com/q/30542428:

`mallopt()` could set parameters to control behavior of `malloc()`, and there is a parameter named `M_MMAP_THRESHOLD`, in general:

- If requested memory is less than it, `brk()` will be used;
- If requested memory is larger than or equals to it, `mmap()` will be used;

The default value of the parameter is `128kb`
melkor
2021-07-18 20:05:02 +08:00
如何判断是 stack 区呢? 7f 看起来也就是差不多中间的地方,可能是 mmap 的区域
turi
2021-07-18 21:20:04 +08:00
你把当前 ebp 地址打印出来对比看看
wms
2021-07-19 08:51:29 +08:00
你的栈有 841GB?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/790194

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX