7

我知道对使用placement new 创建的变量调用delete 然后访问该内存块具有未定义的行为。

int* x = new int[2];
char* ch = new(x) char();
*ch = 't';
delete ch;

但是,如果在堆栈上分配内存块而不是堆,然后我们对该变量调用 delete 然后访问内存,我会收到块类型无效的异常。

int x[2];
char* ch = new(x) char();
*ch = 't';
delete ch;

所以问题清单是:

  • 异常是由于在堆栈上调用 delete 引起的吗?
  • 可以在堆栈上的内存块上使用新的放置吗?
  • 如果是,那么我该如何删除字符指针。
  • 是否可以使用placement new 在单个内存块上分配多个变量?
4

1 回答 1

16

异常是由于在堆栈上调用 delete 引起的吗?

是的。虽然需要澄清一点,但这不是 C++ 例外。这是运行时检测到的错误。如果运行时不是那么聪明,您也可能会遇到未定义的行为。

可以在堆栈上的内存块上使用新的放置吗?

是的。您还可以查看alloca()可变长度数组(VLA) - 这是另外两种在堆栈上分配内存的机制。请注意,VLA 是 C99 的一部分,而不是 C++11(和更早的)标准,但大多数生产级编译器都支持它作为扩展(它可能出现在 C++14 中)。

如果是,那么我该如何删除字符指针。

你不应该。当你使用一个放置 new 时,你不调用delete,你只是调用一个析构函数。对于任何给定o类型的对象,T您需要调用o->~T();而不是delete o;. 但是,如果您必须处理调用deletedelete []处理此类对象的代码,则可能需要重载运算符delete并使delete[]这些运算符不执行任何操作(此时已运行析构函数)。

是否可以使用placement new 在单个内存块上分配多个变量?

是的。但是,您需要格外小心,以确保满足对齐要求

于 2013-07-14T14:08:48.163 回答