c++ - 重载运算符 new[] 的行为取决于析构函数
问题描述
以下代码片段重载operator new[]
并打印出size
所需的指针地址
class MyClass
{
private:
int _data; //sizeof(MyClass) == 4
public:
void* operator new[](size_t size)
{
cout << "MyClass::operator new[]" << endl;
cout << "size = " << size << endl;
void* p = malloc(size);
cout << "p = " << p << endl;
return p;
}
};
int main()
{
MyClass* a = new MyClass[100];
cout << "a = " << a << endl;
}
输出
>> MyClass::operator new[]
>> size = 400
>> p = 0x55e335a3f280
>> a = 0x55e335a3f280
但是,通过显式添加/定义析构函数
class MyClass
{
...
public:
...
~MyClass() {}
};
int main()
{
MyClass* a = new MyClass[100];
cout << "a = " << a << endl;
}
结果改变了
>> MyClass::operator new[]
>> size = 408
>> p = 0x564f30cd7280
>> a = 0x564f30cd7288
表示表达式new[]
正在从 . 请求额外的 8 字节内存operator new[]
。额外的内存字节似乎是存储数组的大小,甚至可以访问!
cout << "info: " << *(reinterpret_cast<size_t*>(a) - 1) << endl;
结果
>> info: 100
我的问题是谁以及为什么使用这 8 个字节的信息?这是标准的一部分吗?如果是这样,是否有解释为什么它被设计成这样?
解决方案
未指定调用任何数组时是否存在以及有多少开销new
。这种行为完全在编译器的宽容范围之内。额外的空间通常用于指示数组中有多少元素。
在调用delete[]
时,需要调用每个元素的析构函数;这只有在我们知道有多少元素的情况下才能做到。在元素具有微不足道的析构函数的情况下,不需要调用它们,因此不需要空间。
请注意,尽管实现通常委托给std::free
in operator delete
,但不能保证,您也应该重载operator delete
。
推荐阅读
- javascript - 我们如何使用 React-bootstrap-table2 为以下 2 个逻辑添加一个格式化程序函数
- swift - SwiftUI: Convert from a CGPoint on screen to a CGPoint in a view
- assembly - Clearing all starting ASCII 0's from a string in x64 NASM
- wpf - WPF: How can I use tag for specifying button's action?
- javascript - 从具有未知嵌套数的数组中递归过滤对象
- sql - 我可以为时间戳模式指定 Kafka JDBC 连接器的查询吗?
- google-sheets - 如何根据单独列中的值对表进行条件格式化?
- office-addins - Addin word : 从 base64 文件加载页眉和页脚
- python - 使用一个或多个 docker 容器(来自 withing python)?
- linux - 如何为 execv 添加到 *argv?