发现了一个知识盲点。当我用malloc
申请很大一段内存(100000 * sizeof(int)
)的时候,返回一个0x229feb0
地址,看大小应该是处于 heap 区,很合理。但是当我用realloc
重新修改大小为 100001 后,居然返回了0x7f6317307010
,看大小好像是处于 stack 区?
同时我发现,如果malloc
只申请一小段内存(比如 100 个int
大小),再用realloc
修改为 101 个int
大小,则不会出现这个问题。返回的地址都似乎是处于 heap (0x2394ef0
和0x2393eb0
)。
请问这可能是什么缘故呢?我看了下汇编代码似乎除了数字之外其余都一样。
示例代码:
int
https://godbolt.org/z/93PoWWdcbint
https://godbolt.org/z/8oYG3s8Mc 1
GeruzoniAnsasu 2021-07-18 14:27:24 +08:00
…… 什么叫看大小处于 stack 区,一个进程是可以分配很多个 heap 区的,建议确认一下内存映射,我猜只是给你分了一块新的 heap 而已
|
2
codehz 2021-07-18 14:35:27 +08:00
(linux 的 glibc 会在一定范围内使用 brk,超过的就是 mmap
|
3
dangyuluo OP @GeruzoniAnsasu 我知道 heap 在真实内存里很跳跃,但是这是虚拟地址,不太明白为什么会从 heap 另一端取地址
@codehz 很有道理!我还在猜是不是有个阈值使 malloc 有不同的操作 |
4
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` |
5
melkor 2021-07-18 20:05:02 +08:00 via iPhone
如何判断是 stack 区呢? 7f 看起来也就是差不多中间的地方,可能是 mmap 的区域
|
6
turi 2021-07-18 21:20:04 +08:00
你把当前 ebp 地址打印出来对比看看
|
7
wms 2021-07-19 08:51:29 +08:00
你的栈有 841GB?
|