c++ - NoFieldsClass::operator new(std::size_t):标准是否允许它每次调用时返回相同的地址?
问题描述
作为优化策略的一部分,我想“假装”我实际上是在堆上分配一个对象,而实际上我只是重用一个预先存在的对象,而应用程序的其余部分却没有注意到,因为没有检查在返回的地址上执行,并且不需要访问对象中的任何字段。除此之外,类构造函数没有副作用。
因此,我想知道以下程序是否表现出按照标准的定义明确、特定于实现、未定义或完全无效的行为。
#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 似乎它是无效的:
如果一个对象嵌套在另一个对象中,或者至少一个是大小为零的子对象并且它们属于不同类型,则两个具有重叠生命周期且不是位域的对象可能具有相同的地址;否则,它们具有不同的地址并占用不相交的存储字节²⁹。
然而,上述段落所指的注释 29 指出:
在“as-if”规则下,如果程序无法观察到差异,则允许实现将两个对象存储在同一机器地址或根本不存储对象。
如开头所述,在我的情况下,程序并不关心分配此对象的地址,所需要的只是它可以分配operator new
和摆脱 with operator delete
,所以它似乎适合注释 29 提出的要求。这是正确的吗?
解决方案
[basic.stc.dynamic.allocation]/2分配函数尝试分配请求的存储量...如果请求成功,则返回的值应为
p0
不同于任何先前返回值 的非空指针值(7.11)p1
, 除非该值p1
随后被传递给operator delete
.
强调我的。
推荐阅读
- r - Json Parse 错误:非法的未引用字符((CTRL-CHAR,代码 10)-(httr:: POST in R)
- php - PHP - preg_replace() 模式无法正常工作
- microsoft-graph-api - 订阅推送通知期间出现超时错误
- php - 函数 ip2long 在类中失败
- python - Python脚本无限迭代文本文件
- php - 从 Blade 文件转换或使用 Laravel 路由以在 Vue 组件中使用
- python - pandas:使用 d[condition] 和 d.loc[condition] 选择行之间的区别?(并将值设置为返回的行)
- java - @Document 不在 Spring Boot 应用程序中创建集合
- javascript - 将对象转换为 MongoDB 中用户的数组
- javascript - JavaScript 实时时钟未运行