关于动态内存分配的C编程面试题

C programming interview question about dynamic memory allocation

提问人:Durvesh Dinesh Bodkar 提问时间:8/5/2023 更新时间:8/7/2023 访问量:95

问:

如果要在堆中动态分配 8 个字节的内存,但这 8 个字节的内存不能连续可用。它在堆中分别作为 5 个字节和 3 个字节提供。那么你能分配内存吗?如果是,如何?

如果是,我们可以只使用 malloc 或 malloc 和 calloc 吗

c 指针 malloc 动态内存分配

评论

4赞 Barmar 8/5/2023
通常,如果需要分配单个对象,则需要内存是连续的。所以答案是否定的。
4赞 Chris 8/5/2023
8 字节的内存在堆上不可用是一个非常小众的极端情况。一个 5 字节的块和一个 3 字节的块是可用的,我觉得它更加小众。
3赞 n. m. could be an AI 8/5/2023
对我来说,这听起来像是一个棘手的问题。我会逃离那个地方。
0赞 Andrew Henle 8/5/2023
@n.m.couldbeanAI 也与编写可移植、可维护的 C 代码完全无关。要么等返回一个有效的指针,要么返回一个,除了接受结果并处理它们之外,你几乎无能为力。如果他们对除了“假的,诡计问题!”之外的任何答案感到满意,是的,逃离那个地方。很远很远。OP:请在您的回答中包含此问题的链接。:-)malloc()NULL
2赞 Weather Vane 8/5/2023
面试问题往往会引发讨论,而不是明确的答案。他们不需要答案,但他们确实需要测试你的知识。如果你不停地重复诸如“技巧问题”之类的东西,或者在另一种情况下重复“未定义的行为”,那么你就没有给他们他们想要的东西。面试(和考试问题)不是关于两个词的答案。

答:

6赞 chqrlie 8/5/2023 #1

堆的粒度通常为 8 或 16 字节。不太可能有 2 个块分别用于 5 个和 3 个字节,并且它们都不能用于 8 个字节的分配。如果内存非常稀缺,您遇到这种情况并分配一个 8 字节块 OR 失败,则不应尝试使用 2 个单独的块来处理需求,而应发出内存不足条件的信号并优雅地处理它。malloc()calloc()

1赞 John Bollinger 8/5/2023 #2

如果要在堆中动态分配 8 个字节的内存,但这 8 个字节的内存不能连续可用。 它在堆中分别作为 5 个字节和 3 个字节提供。 那么你能分配内存吗?

每次成功调用 (or ) 都会分配一个连续的内存块。如果没有足够大的块可用,则 () 将失败。 没有任何方法可以返回不连续的内存块。它不能移动分配的块,因此它不能合并尚未连续的块。malloc()calloc()malloc()calloc()malloc()

那么,你能分配一个 8 字节的块吗?不可以。

你能分配两个块,总大小为 8 字节吗?如果我们将问题理解为断言可以单独分配 5 字节块和单独的 3 字节块,那么是的:这是问题规定的。如果这是实际被问到的问题,那么潜在的问题可能是你如何发现 5 字节和 3 字节的块是可用的。没有内存自省机制可以查找可用块的组合,但您可以简单地尝试越来越小的大小,直到找到一个有效的大小,然后看看是否可以分配其余的块。例如:

void allocate8(void **ret1, void **ret2) {
    void *p1 = NULL;
    void *p2 = NULL;

    for (int i = 8; i >= 4; i--) {
        p1 = malloc(i);
        if (p1) {
            if (i < 8) {
                p2 = malloc(8 - i);
                if (!p2) {
                    free(p1);
                    p1 = NULL;
                }
            }
            break;
        }
    }

    *ret1 = p1;
    *ret2 = p2;
}

但这有用吗?几乎可以肯定不是。

1赞 Cebul 8/5/2023 #3

如果我正确理解了您描述的问题,它涉及内存碎片。不幸的是,作为开发人员,您无法解决这个问题,尤其是仅限于 malloc() 和 calloc() 函数,您能做的最好的事情就是意识到问题并尝试抓住它。该问题的解决方案取决于系统中使用的内存分配器。