为什么realloc小块内存成功,而重新分配大块内存失败?

3
这段代码会使得x指向一个100GB大小的内存块。
#include <stdlib.h>
#include <stdio.h>

int main() {
    auto x = malloc(1);
    for (int i = 1; i< 1024; ++i) x = realloc(x, i*1024ULL*1024*100);
    while (true); // Give us time to check top
}

虽然这段代码无法分配内存。

#include <stdlib.h>
#include <stdio.h>

int main() {
    auto x = malloc(1024ULL*1024*100*1024);
    printf("%llu\n", x);
    while (true); // Give us time to check top
}

第二段代码的错误在哪里?只是分配没有出现在“top”上吗?不管怎样,我强烈建议检查“malloc()”和“realloc()”的返回值,以查看您的“malloc()”实现是否因某些原因而退出。 - cmaster - reinstate monica
@cmaster 我一会儿就编辑问题。但我添加了一个检查,第二个示例中的 x 为空。但是,确实,它在 top 中没有显示出来。 - chew socks
2个回答

1

在成功的那个中,您分配的内存较少:

for (int i = 1; i< 1024; ++i) x = realloc(x, i*1024ULL*1024*100);

最后一个 realloc 是:
x = realloc(x, 1023 * (1024ULL*1024*100));

与之相比:
auto x = malloc(1024 * (1024ULL*100*1024));

也许这正是你的记忆边界 - 最后的100M让骆驼垮了?

猜得不错 ;) 但我把它改成了 i <= 1024,它仍然可以工作。 - chew socks

1
我的猜测是,您的系统内存大小小于您正在尝试分配的100 GiB。虽然Linux确实会超额提交内存,但仍会放弃那些远远超出其能够满足的请求。这就是为什么第二个示例失败的原因。
另一方面,第一个示例的许多小增量远低于该阈值。因此,由于内核知道您尚未需要任何先前的内存,因此每个增量都成功了,因此它没有迹象表明它将无法支持那100 MiB 的内存。
我相信,进程内存请求失败的阈值相对于可用RAM,并且可以进行调整(尽管我不记得具体如何)。

我有16GiB的RAM和8GiB的交换空间。 - chew socks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接