C++17(草案N4659)[basic.compound]/3中写道:
指针类型的每个值都是以下类型之一:
指向对象或函数的指针(指针被称为指向该对象或函数),或
指向对象末尾之后的指针([expr.add]),或
该类型的空指针值([conv.ptr]),或
无效指针值。
在下面的程序中,分配给对象寿命以外的内存的指针属于这些类别中的哪一个,特别是在// (1)
到// (3)
处的a
和// (4)
处的b
的值?
#include<new>
#include<algorithm>
struct S {
~S() { /* Non-trivial destructor */ }
};
struct T {
~T() { /* Non-trivial destructor */ }
};
int main() {
void* a = operator new(std::max(sizeof(S), sizeof(T)));
// (1)
a = new(a) S;
static_cast<S*>(a)->~S();
// (2)
a = new(a) T;
static_cast<T*>(a)->~T();
// (3)
operator delete(a);
void* b = operator new(42);
// (4)
operator delete(b);
}
在我看来,指针变量的值在被释放时会变得无效,而不是当对象的生命周期结束时,但如果指针变量是指向一个对象的话,那它指向的是哪个对象呢?
operator delete()
函数返回时),任何指向其底层内存的指针也将变为无效。 - Peteroperator new
返回一个指向已分配内存块的第一个字节的指针。您可以考虑在链接中的注释“注意:指向void的指针没有对象类型的指针,因为void不是对象类型。-结束注释”。即使在对象被销毁后,a
和b
仍然指向内存。析构函数不会为已分配的内存调用delete
。也许在所有情况下它都是“对象类型的指针”,但是您在使用<new>
时结合了概念,这重新引入了类似于C风格的malloc
和free
的分配方式。 - JHBonariusvoid*
是一个“对象指针类型”,而引用的段落谈论的是“指针类型”的每个值,我认为这是“对象指针类型”的超集。我完全知道operator new
返回分配内存的指针,并且析构函数调用不会释放它。<new>
包含了非分配放置 new 的实现。std::free
和std::malloc
声明在<cstdlib>
中,而不是<new>
。 - walnut