c++ - NoFieldsClass::operator new(std::size_t):标准是否允许它在每次调用时返回相同的地址?

标签 c++ memory-management language-lawyer new-operator

作为优化策略的一部分,我想“假装”我实际上在堆上分配一个对象,而实际上我只是重用一个预先存在的对象,而应用程序的其余部分根本没有注意到,因为不会对返回的地址执行任何检查,也不需要访问对象中的任何字段。除此之外,类构造函数没有副作用。

因此,我想知道根据标准,以下程序是否表现出定义明确、特定于实现、未定义或完全无效的行为。

#include <memory>
#include <cassert>

class Base {
public:
    Base(){}
    virtual ~Base(){}
};

class Derived: public Base {
public:
    using Base::Base;

    static void *operator new(std::size_t s)  {
        static void *mem = ::operator new(s);

        return mem;
    }

    static void operator delete(void *mem) {
        /* no-op */
    }
};

int main() {
    using Ptr = std::unique_ptr<Base>;

    Ptr p1 { new Derived };
    Ptr p2 { new Derived };
    Ptr p3 { new Derived };
    Ptr p4 { new Derived };

    // assert just in this test, not in the real program
    assert(p1 == p2 && p2 == p3 && p3 == p4);

    return 0;
}

阅读当前 C++ 工作草案(N4835)的 §6.7.2.9 似乎无效:

Two objects with overlapping lifetimes that are not bit-fields may have the same address if one is nested within the other, or if at least one is a subobject of zero size and they are of different types; otherwise, they have distinct addresses and occupy disjoint bytes of storage ²⁹.

但是,上一段所指的注释 29 指出:

Under the “as-if” rule an implementation is allowed to store two objects at the same machine address or not store an object at all if the program cannot observe the difference.

如开头所述,在我的例子中,程序根本不关心这个对象的分配地址,所需要的只是可以用 operator new 和使用 operator delete 删除,因此它似乎符合注释 29 的要求。这是正确的吗?

最佳答案

[basic.stc.dynamic.allocation]/2 The allocation function attempts to allocate the requested amount of storage... If the request succeeds, the value returned shall be a non-null pointer value (7.11) p0 different from any previously returned value p1, unless that value p1 was subsequently passed to an operator delete.

强调我的。

关于c++ - NoFieldsClass::operator new(std::size_t):标准是否允许它在每次调用时返回相同的地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58572372/

相关文章:

c++ - 如何转换dfs

c++ - boost::make_shared 底层对象和引用计数对象的内存分配大小在哪里?

java - 释放 java.util.LinkedList$Entry 内存

c++ - 结束的随机访问迭代器可以递增零吗?

c++ - 三路运算符 <=> 返回带有隐式转换函数的结构体

c++ - 将 std::vector 作为指针引用传递

c++ - 异常后重置 Cuda 上下文

c++ - 提取函数会影响性能吗?

android - 声音 fragment 的堆大小溢出问题

C++:一个对象既可以存储也可以不存储吗?