malloc如何使用严格的别名-只能在单个编译单元中违反它吗?

问题描述 投票:2回答:2

[阅读this之后,我有一个类似this one的问题,想知道内存分配器如何在不违反严格的别名规则的情况下工作。但是我并不在意重新使用释放的内存,我在想如何在不违反严格的别名的情况下将分配的对象放置在线性内存中。

到目前为止,我看过的所有堆内存分配器将它们的内存划分为某种类型的块,并在其前面放置一个标题。但是,malloc返回void *,通常指向标头之后的内存。这是一个非常狭窄的示例来说明这一点。

#include <stddef.h>

struct block_header {
  size_t size;
};

struct block_header *request_space(size_t size);

void *malloc(size_t size) {
    struct block_header *block = request_space(size);

    // I guess this violates strict aliasing, because the caller will 
    // convert the pointer to something other than struct block_header?
    // Or why wouldn't it?
    return block + 1;
}

我已经看了一段时间了,但是我看不到分配器如何在不违反严格别名的情况下将其指针放置在内存区域中。我想念什么?

c pointers language-lawyer c11 strict-aliasing
2个回答
0
投票

malloc的源代码不需要以常规源代码的方式符合C标准。它是C实现的一部分。

malloc的工作人员,编译器和C实现的其他部分负责确保他们一起工作。这可以包括编译器使用C编译器而非C标准保证的行为来特别对待mallocmalloc


0
投票

C标准故意避免要求所有实现都适合所有目的。相反,它旨在允许用于各种目的的实现(以“符合语言扩展”的形式)以有意义的方式有意义地构建过程,即使该标准没有任何要求,该构造也可用于那些目的。因此,该标准允许旨在用于需要手动内存管理的任务的实现支持支持此类任务的“流行扩展”,即使它故意避免了非旨在用于此类任务的实现也需要此类支持。

许多类型的内存分配器在其语义仅限于标准所规定的实现上是不切实际的。但是,遵循委员会描述为“不要阻止程序员做需要做的事情”的C精神的实现,并且被设计和配置为适合于构建这样的分配器的实现将识别出以下迹象:存储将被用作多种类型。编译器识别出此类指示的确切情况范围被视为标准管辖范围之外的“实施质量”问题。从实际的角度来看,clang和gcc的作者选择以最低允许质量的方式工作,除非使用-fno-strict-aliasing,但是这意味着想要对这些编译器做任何“有趣的事情”的程序员必须使用选项。没有任何证据表明该标准的作者希望程序员应无所适从,以适应劣质实现的局限性。相反,他们希望市场比委员会能够更好地判断编译器应如何最有效地执行各种任务。

© www.soinside.com 2019 - 2024. All rights reserved.