5

在查看遗留代码时,我发现类似于以下代码

void* legacy_type::operator new(size_t size) {
    return pool_alloc(size);
}

众所周知,pool_alloc 在失败的情况下永远不会抛出并返回 0。

这里的 new 的 std::nothrow 变体没有重载。

我想知道这段代码在语义上是否正确并且具有明确定义的行为。

应该new (std::nothrow) legacy_type;使用自定义 pool_alloc 吗?在我的编译器中,它根本无法编译。它是明确定义的行为吗?

this==0如果重载operator new返回零,构造函数是否应该运行并崩溃?在我的编译器中它运行(并在成员初始化时崩溃)。它是标准的定义良好的行为吗?

4

1 回答 1

2

1)不,不应该。这些是不同的功能。并且,当您重载其中一项操作时 - 如果未重载,所有其他操作将永远不会起作用,因为如果operator new在类范围内并且签名不可接受,则编译器将不会搜索 global operator new,因此,编译错误会发生的。

2)如果你new将返回空指针,你会打破后置条件。n3376 18.6.1.1/3

要求的行为:返回一个指向适当对齐存储的非空指针(3.7.4),否则抛出一个 bad_alloc 异常。此要求对该功能的替换版本具有约束力。

如果要返回 0,则应使用以下签名

void* operator new(size_t) throw()

如果您使用此重载并从中返回 0,则没有 seg-fault。

n3376 5.3.4/13

如果分配函数返回null,则不进行初始化,不调用释放函数,new-expression 的值为null。

于 2013-10-31T12:51:30.163 回答